home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / hprpldev.tar / rplman.doc < prev    next >
Text File  |  1991-07-12  |  263KB  |  8,383 lines

  1.  
  2.  
  3.  
  4.                                  CONTENTS
  5.  
  6.  
  7.         1.  Introduction......................................    1
  8.  
  9.         2.  RPL Principles....................................    2
  10.             2.1   Origins.....................................    2
  11.             2.2   Mathematical Control........................    3
  12.             2.3   Formal Definitions .........................    5
  13.             2.4   Execution...................................    6
  14.                   2.4.1    EVAL...............................    8
  15.                   2.4.2    Data Class Objects.................    9
  16.                   2.4.3    Identifier Class Objects...........    9
  17.                   2.4.4    Procedure Class Objects............   10
  18.                   2.4.5    Object Skipover and SEMI...........   10
  19.                   2.4.6    RPL Pointers.......................   11
  20.             2.5   Memory Management...........................   11
  21.             2.6   User RPL and System RPL.....................   13
  22.             2.7   Programming in System RPL...................   14
  23.             2.8   Sample RPL Program..........................   16
  24.                   2.8.1    The Source File....................   16
  25.                   2.8.2    Compiling the Program..............   18
  26.  
  27.         3.  Object Structures.................................   19
  28.             3.1   Object Types................................   19
  29.                   3.1.1    Identifier Object..................   19
  30.                   3.1.2    Temporary Identifier Object........   19
  31.                   3.1.3    ROM Pointer Object.................   20
  32.                   3.1.4    Binary Integer Object..............   20
  33.                   3.1.5    Real Number Object.................   20
  34.                   3.1.6    Extended Real Number Object........   21
  35.                   3.1.7    Complex Number Object..............   22
  36.                   3.1.8    Extended Complex Number
  37.                            Object.............................   22
  38.                   3.1.9    Array Object.......................   23
  39.                   3.1.10   Linked Array Object................   23
  40.                   3.1.11   Character String Object............   25
  41.                   3.1.12   Hex String Object..................   25
  42.                   3.1.13   Character Object...................   25
  43.                   3.1.14   Unit Object........................   26
  44.                   3.1.15   Code Object........................   26
  45.                   3.1.16   Primitive Code Object..............   27
  46.                   3.1.17   Program Object.....................   27
  47.                   3.1.18   List Object........................   28
  48.                   3.1.19   Symbolic Object....................   28
  49.                   3.1.20   Directory Object...................   29
  50.                   3.1.21   Graphics Object....................   29
  51.             3.2   Terminology and Abbreviations...............   30
  52.  
  53.         4.  Binary Integers...................................   32
  54.             4.1   Built-in Binary Integers....................   32
  55.             4.2   Binary Integer Manipulation.................   34
  56.                   4.2.1    Arithmetic Functions...............   34
  57.                   4.2.2    Conversion Functions...............   35
  58.  
  59.         5.  Character Constants...............................   36
  60.  
  61.         6.  Hex & Character Strings...........................   37
  62.  
  63.  
  64.  
  65.                                   - i -
  66.  
  67.  
  68.  
  69.  
  70.             6.1   Character Strings...........................   37
  71.             6.2   Hex Strings.................................   39
  72.  
  73.         7.  Real Numbers......................................   41
  74.             7.1   Built-in Reals..............................   41
  75.             7.2   Real Number Functions.......................   41
  76.  
  77.         8.  Complex Numbers...................................   46
  78.             8.1   Built-in Complex Numbers....................   46
  79.             8.2   Conversion Words............................   46
  80.             8.3   Complex Functions...........................   46
  81.  
  82.         9.  Arrays............................................   48
  83.  
  84.        10.  Composite Objects.................................   49
  85.  
  86.        11.  Tagged Objects....................................   51
  87.  
  88.        12.  Unit Objects......................................   52
  89.  
  90.        13.  Temporary Variables and Temporary
  91.             Environments......................................   54
  92.             13.1  Structure of the Temporary Environment
  93.                   Area........................................   55
  94.             13.2  Named vs. Unnamed Temporary Variables.......   57
  95.             13.3  Provided Words for Temporary Variables......   59
  96.             13.4  Coding Suggestions..........................   60
  97.  
  98.        14.  Checking Arguments................................   61
  99.             14.1  Number of Arguments.........................   62
  100.             14.2  Dispatching on Argument Type................   63
  101.             14.3  Examples....................................   66
  102.  
  103.        15.  Loop Control Structures...........................   68
  104.             15.1  Indefinite Loops............................   68
  105.             15.2  Definite Loops..............................   70
  106.                   15.2.1   Provided Words.....................   70
  107.                   15.2.2   Examples...........................   71
  108.  
  109.        16.  Error Generation & Trapping.......................   73
  110.             16.1  Trapping: ERRSET and ERRTRAP................   73
  111.             16.2  Action of ERRJMP............................   73
  112.             16.3  The Protection Word.........................   74
  113.             16.4  Error Words.................................   75
  114.  
  115.        17.  Test and Control..................................   76
  116.             17.1  Flags and Tests.............................   76
  117.                   17.1.1   General Object Tests...............   77
  118.                   17.1.2   Binary Integer Comparisons.........   78
  119.                   17.1.3   Decimal Number Tests...............   79
  120.             17.2  Words that Operate on the Runstream.........   80
  121.             17.3  If/Then/Else................................   83
  122.             17.4  CASE words..................................   84
  123.  
  124.        18.  Stack Operations..................................   87
  125.  
  126.        19.  Memory Operations.................................   89
  127.             19.1  Temporary Memory............................   89
  128.  
  129.  
  130.  
  131.                                   - ii -
  132.  
  133.  
  134.  
  135.  
  136.             19.2  Variables and Directories...................   89
  137.                   19.2.1   Directories........................   91
  138.             19.3  The Hidden Directory........................   92
  139.             19.4  Additional Memory Utilities.................   93
  140.  
  141.        20.  Display Management & Graphics.....................   94
  142.             20.1  Display Organization........................   94
  143.             20.2  Preparing the Display.......................   95
  144.             20.3  Controlling Display Refresh.................   96
  145.             20.4  Clearing the Display........................   97
  146.             20.5  Annunciator Control.........................   97
  147.             20.6  Display Coordinates.........................   98
  148.                   20.6.1   Window Coordinates.................   98
  149.             20.7  Displaying Text.............................   99
  150.                   20.7.1   Standard Text Display Areas........   99
  151.                   20.7.2   Temporary Messages.................  101
  152.             20.8  Graphics Objects............................  102
  153.                   20.8.1   Warnings...........................  102
  154.                   20.8.2   Graphics Tools.....................  103
  155.                   20.8.3   Grob Dimensions....................  104
  156.                   20.8.4   Built-in Grobs.....................  104
  157.                   20.8.5   Menu Display Utilities.............  105
  158.             20.9  Scrolling the Display.......................  105
  159.  
  160.        21.  Keyboard Control..................................  109
  161.             21.1  Key Locations...............................  109
  162.             21.2  Waiting for a Key...........................  110
  163.             21.3  InputLine...................................  111
  164.                   21.3.1   InputLine Example..................  112
  165.             21.4  The Parameterized Outer Loop................  113
  166.                   21.4.1   The Parameterized Outer Loop
  167.                            Utilities..........................  114
  168.                   21.4.2   Overview of the Parameterized
  169.                            Outer Loop.........................  115
  170.                   21.4.3   Handling Errors with the
  171.                            Utilities..........................  116
  172.                   21.4.4   The Display........................  116
  173.                   21.4.5   Error Handling.....................  117
  174.                   21.4.6   Hard Key Assignments...............  117
  175.                   21.4.7   Menu Key Assignments...............  119
  176.                   21.4.8   Preventing Suspended
  177.                            Environments.......................  120
  178.                   21.4.9   Specifying an Exit Condition.......  120
  179.                   21.4.10  ParOuterLoop Example...............  121
  180.  
  181.        22.  System Commands...................................  123
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.                                  - iii -
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.                           RPL PROGRAMMING GUIDE
  206.  
  207.  
  208.  
  209.        1.  Introduction
  210.  
  211.        The HP 48 calculator was designed to be a customizable
  212.        mathematical scratchpad for use by students and
  213.        professionals in technical fields.  In many respects it is a
  214.        descendent of the HP 41, providing a much broader and more
  215.        sophisticated computation capability than the HP 41, but
  216.        preserving its RPN/key-per-function orientation.
  217.  
  218.  
  219.        The HP 48 uses the so-called Saturn architecture, named by
  220.        the code name of the original CPU designed for the HP 71B
  221.        handheld computer.  It also uses a custom operating
  222.        system/language called RPL, which was designed to provide
  223.        symbolic mathematical capabilities, executing from ROM in a
  224.        limited RAM environment (it is today still the only symbolic
  225.        system that can run in ROM).  The combination of specialized
  226.        hardware and firmware makes it relatively difficult to
  227.        develop application software for the HP48, and accordingly
  228.        the HP48 is not positioned as a primary external application
  229.        vehicle.  The orientation of the product and its user
  230.        programming language is towards simple customization by the
  231.        primary user.
  232.  
  233.        Despite these barriers, the price and physical configuration
  234.        of the HP48 make it a desirable application platform for
  235.        many software developers, especially those who want to
  236.        target customers in the HP48's normal markets.  The user
  237.        language is suitable for simple programs, but for elaborate
  238.        systems, the intentional error protection and other overhead
  239.        can result in substantial performance penalties compared
  240.        with the programs using the full range of system calls.
  241.  
  242.        In this document, we will provide a description of the
  243.        design and conventions of the RPL language.  The material
  244.        here should provide enough detail to permit the creation of
  245.        RPL programs and other objects, using the associated IBM
  246.        PC-based compilation tools.  Included is documention of a
  247.        large number of system RPL objects that are useful utilities
  248.        for program development.
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.                                   Page 1
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.        2.  RPL Principles
  271.  
  272.        (The following material was excerpted from "RPL: A
  273.        Mathematical Control Language", by W. C. Wickes, published
  274.        in "Programming Environments", Institute for Applied Forth
  275.        Research, Inc., 1988)
  276.  
  277.  
  278.        2.1  Origins
  279.  
  280.        In 1984, a project was started at Hewlett-Packard Corvallis
  281.        Division to develop a new software operating system to
  282.        streamline calculator development and support a new
  283.        generation of hardware and software.  Previously, all HP
  284.        calculators were implemented entirely in assembly language,
  285.        a process that was becoming increasingly cumbersome and
  286.        inefficient as the memory sizes of the calculators
  287.        increased.  The objectives for the new operating system were
  288.        as follows:
  289.  
  290.           + To provide execution control and memory management,
  291.             including plug-in memory;
  292.  
  293.           + To provide a programming language for rapid prototyping
  294.             and application development;
  295.  
  296.           + To support a variety of business and technical
  297.             calculators;
  298.  
  299.           + To execute identically out of RAM and ROM;
  300.  
  301.           + To minimize memory use, especially RAM;
  302.  
  303.           + To be transportable to various CPU's;
  304.  
  305.           + To be extensible; and
  306.  
  307.           + To support symbolic mathematical operations.
  308.  
  309.        Several existing operating systems and languages were
  310.        considered, but none could meet all of the design
  311.        objectives.  A new system was therefore developed, which
  312.        merges the threaded interpretation of Forth with the
  313.        functional approach of Lisp.  The resulting operating
  314.        system, known unofficially as RPL (for Reverse-Polish Lisp),
  315.        made its first public appearance in June of 1986 in the HP-
  316.        18C Business Consultant calculator.  Subsequently, RPL has
  317.        been the basis for the HP-17B, HP-19B, HP-27S, HP-28C and
  318.        HP-28S, and HP 48S and HP 48SX calculators.  The HP-17B,
  319.        18C, and 19B are designed for business applications; they
  320.        and the HP-27S scientific calculator offer an ``algebraic''
  321.        calculating logic, and the underlying operating system is
  322.        invisible to the user.  The HP 28/HP 48 families of
  323.        scientific calculators use an RPN logic, and many of the
  324.        facilities of operating system are directly available as
  325.        calculator commands.
  326.  
  327.  
  328.  
  329.                                   Page 2
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.        2.2  Mathematical Control
  337.  
  338.        The official operating system objectives listed above were
  339.        blended throughout the RPL development cycle with a less
  340.        formal objective of creating a mathematical control language
  341.        that would extend the ease-of-use and interactive nature of
  342.        a calculator to the realm of symbolic mathematical
  343.        operations.  A calculator is distinguished from a computer
  344.        in this context by:
  345.  
  346.           + very compact size;
  347.  
  348.           + ``instant on''--no warm-up or software
  349.             loading/bootstrapping;
  350.  
  351.           + dedicated keys for common operations rather than qwerty
  352.             keyboards.
  353.  
  354.           + ``instant action'' when a function key is pressed.
  355.  
  356.        The HP-28, which was developed by the same team that created
  357.        the RPL operating system, was the first realization of this
  358.        background objective; the HP 48 is the latest and most
  359.        mature implementation.
  360.  
  361.        Much of the design of RPL can be derived from a
  362.        consideration of the manner in which ordinary mathematical
  363.        expressions are evaluated.  Consider, for example, the
  364.        expression
  365.  
  366.                              1+ 2 sin(3x) +4
  367.  
  368.        As any RPN enthusiast knows, the expression as written here
  369.        does not correspond in its left-to-right order to the order
  370.        in which a human or a machine could actually carry out the
  371.        calculation.  For example, the first sum has to be delayed
  372.        until after several other steps are executed.  Rewriting the
  373.        expression in RPN form, we obtain a representation that is
  374.        also executable in its written order:
  375.  
  376.                  1   2   3   x   *   sin   *   +   4   +
  377.  
  378.        To translate this sequence into a control language, we need
  379.        to formalize several concepts.  First, we use the generic
  380.        term object to refer to each step in the sequence, such as
  381.        1, 2, or sin.  Even in this simple example, there are three
  382.        classes of objects:
  383.  
  384.          1.  Data objects.  Execution of an object such as 1, 2, or
  385.              3 in the example just returns the value of the object.
  386.  
  387.          2.  Names.  The symbol x must be the name of some other
  388.              object; when x is executed, the named object is
  389.              substituted for the symbol.
  390.  
  391.  
  392.  
  393.  
  394.  
  395.                                   Page 3
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.          3.  Procedures.  Objects such as *, sin, and + represent
  403.              mathematical operations, which are applied, for
  404.              example, to data objects to create new data objects.
  405.  
  406.        The concept of an object is closely tied to the concept of
  407.        execution, which can be thought of as the "activation" of an
  408.        object.  An individual object is characterized by its object
  409.        type, which determines its action when executed, and its
  410.        value, which distinguishes it from another of the same type.
  411.  
  412.        Expression evaluation in these terms becomes the sequential
  413.        execution of a series of objects (the objects representing
  414.        the RPN form of the expression).  Two constructs are
  415.        necessary to make the execution coherent: an object stack
  416.        and an interpreter pointer.  The first construct provides a
  417.        place from which procedure objects can take their arguments
  418.        and to which they can return their result objects.  A LIFO
  419.        stack as used in Forth is ideal for this purpose, and such a
  420.        stack is included in RPL.  The interpreter pointer is just a
  421.        program counter that indicates the next object to be
  422.        executed.  The interpreter pointer should be distinguished
  423.        from the CPU program counter, which indicates the next CPU
  424.        instruction.
  425.  
  426.        A mathematical expression considered as a sequence of
  427.        objects suggests an additional classification of objects as
  428.        either atomic or composite.  An atomic objects is an object
  429.        that cannot be taken apart into stand-alone objects;
  430.        examples are a simple data object like 1 or 2, or perhaps an
  431.        object like * or + that is implemented normally in assembly
  432.        language.  A composite object is a collection of other
  433.        objects.  In Forth, a secondary word is an example of a
  434.        composite object.  RPL provides at least three types of
  435.        composite objects: secondaries, which are prcedures defined
  436.        as unrestricted sequences of objects; symbolics, which are
  437.        sequences of objects that must be logically equivalent to
  438.        algebraic expressions; and lists, which contain objects
  439.        collected for any logical purpose other than sequential
  440.        execution.
  441.  
  442.        The final point in this brief mathematics-to-RPL derivation
  443.        is the observation that the definition of composite objects
  444.        leads to the concepts of threaded interpretation and a
  445.        return stack.  That is, in the example it it easy to imagine
  446.        that the name object x could represent a composite object
  447.        that in turn represents another expression.  In that case,
  448.        one would expect execution of x to cause the intepreter
  449.        pointer to jump to the sequence of objects referenced by x,
  450.        while the location of the object following x in the original
  451.        is stored so that execution can later return there.  This
  452.        process should be able to be indefinitely repeated, so RPL
  453.        provides a LIFO stack for the return objects.
  454.  
  455.        The preceding introduction might in some respects also have
  456.        been an introduction for the derivation of Forth, if
  457.        questions of floating-point versus integer arithmetic are
  458.  
  459.  
  460.  
  461.                                   Page 4
  462.  
  463.  
  464.  
  465.  
  466.        ignored.  In particular, both systems use threaded
  467.        interpretation and a LIFO data stack for interchange of
  468.        objects.  However, there are several important differences
  469.        between Forth and RPL:
  470.  
  471.           + RPL supports both direct and indirect threaded
  472.             execution in a completely uniform manner.
  473.  
  474.           + RPL supports dynamic allocation of its objects.
  475.  
  476.           + RPL code is, in general, completely relocatable.
  477.  
  478.  
  479.        2.3  Formal Definitions
  480.  
  481.        This section will present the abstract definitions of RPL
  482.        that are independent of any particular CPU or
  483.        implementation.
  484.  
  485.        The fundamental structure in RPL is the object.  Any object
  486.        consists of a pair: the prologue address and the object
  487.        body.
  488.                         +---------------+
  489.                         |  -> Prologue  |
  490.                         +---------------+
  491.                         |     Body      |
  492.                         +---------------+
  493.  
  494.        The two parts are contiguous in memory with the prologue
  495.        address part in lower memory The prologue address is that of
  496.        a machine-code routine that executes the object; the body is
  497.        data used by the prologue.  Objects are classified by type;
  498.        each type is associated with a unique prologue.  The
  499.        prologues thus serve a dual purposes of executing an object
  500.        and identifying its type.
  501.  
  502.        An object is either atomic or composite.  A composite object
  503.        is either null or non-null; a non-null composite has a head
  504.        which is an object and a tail which is composite.
  505.  
  506.        In addition to being executed, all RPL objects can be
  507.        copied, compared, embedded in composite objects, and
  508.        skipped.  The latter property implies that the memory length
  509.        of any object is predetermined or can be computed from the
  510.        object.  For atomic objects such as real numbers, the size
  511.        is invariant.  For a more complicated atomic object such as
  512.        a numerical array, the size can be computed from the array
  513.        dimensions that are stored in the body of the array object.
  514.        (RPL arrays are not composite--the elements do not have
  515.        individual prologues and hence are not objects.) Composite
  516.        objects may include a length field or they may end with a
  517.        marker object.
  518.  
  519.        A pointer is an address in the memory space of the CPU, and
  520.        may be a location pointer or an object pointer.  A location
  521.        pointer addresses any part of memory, whereas a object
  522.        pointer point to an object, specifically to the prologue
  523.        location pointer at the start of an object.
  524.  
  525.  
  526.  
  527.                                   Page 5
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.        RPL requires, in addition to the CPU program counters, five
  535.        variables for its fundamental operation:
  536.  
  537.           + The interpreter pointer I.
  538.  
  539.           + The current object pointer O.
  540.  
  541.           + The data stack pointer D.
  542.  
  543.           + The return stack pointer R.
  544.  
  545.           + The amount of free memory M.
  546.  
  547.        In the most general definition of RPL, I is an object
  548.        pointer pointing to a composite object that is the top of a
  549.        stack of composite objects called the runstream.  R points
  550.        to the rest of the runstream stack.  In practical
  551.        implementations, this definition is streamlined by allowing
  552.        I to point to any object embedded in a composite, while R is
  553.        a location pointer pointing to the top of a stack of object
  554.        pointers, each of which points to an embedded object.
  555.  
  556.        It is fundamental to RPL that objects can be executed
  557.        directly or indirectly with equivalent results.  This means
  558.        that an object can be represented anywhere by a pointer to
  559.        the object as well as by the object itself.
  560.  
  561.  
  562.        2.4  Execution
  563.  
  564.        RPL object execution consists of the CPU execution of the
  565.        object's prologue, where the prologue code can access the
  566.        object's body by means of the object pointer O.  Object
  567.        pointer execution is the CPU execution of the pointer's
  568.        addressee.  This interpretive execution is controlled by the
  569.        inner interpreter, or inner loop, which determines the
  570.        sequence of object/object pointer execution.
  571.  
  572.        RPL objects are sorted by their general execution properties
  573.        into three classes:
  574.  
  575.        * Objects that merely return themselves to the data stack
  576.        when executed are called data class objects.  Examples are
  577.        real numbers, strings, and arrays.
  578.  
  579.        * Objects that serve as references for other objects are
  580.        called identifier class objects.  RPL defines three
  581.        identifier class object types: identifier (global name),
  582.        temporary identifier (local name), and ROM pointer (XLIB
  583.        name).
  584.  
  585.        * Objects that contain bodies into which execution flow can
  586.        pass are called procedure class objects.  There are three
  587.        types of procedure class objects: programs (also called a
  588.        "secondaries" or a "colon-definitions" in Forth
  589.        terminology), code objects, and primitive code objects.
  590.  
  591.  
  592.  
  593.                                   Page 6
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.        The RPL inner loop and prologue designs provide for
  601.        interchangeable direct and indirect object execution (note:
  602.        a patent application has been filed for the concepts
  603.        described next). The inner loop consists of the following
  604.        pseudo-code:
  605.  
  606.                              O = [I]
  607.                              I = I + delta
  608.                              PC = [O] + delta
  609.  
  610.        where [x] means the contents of address x, and delta is the
  611.        length of a memory address.  This loop is the same in Forth,
  612.        except that the CPU execution jumps to [O]+delta instead of
  613.        to [O].  This is because all RPL prologues start with their
  614.        own address, which is the feature that makes possible direct
  615.        execution as well as indirect.  Prologues look like this:
  616.  
  617.        PROLOG  ->PROLOG                            Self address
  618.                IF O + delta != PC THEN GOTO REST   Test for direct execution
  619.                O = I - delta                       Correct O
  620.                I = I + len                         Correct I
  621.        REST    (rest of prologue)
  622.  
  623.        Here len is the length of the object body.
  624.  
  625.        When an object is being executed directly, the inner loop
  626.        does not set O or I correctly.  However, a prologue knows it
  627.        is being executed directly by comparing the PC address with
  628.        O and can update the variables accordingly.  A prologue is
  629.        also responsible for preserving the threaded interpretation
  630.        by including a return to the inner loop at its end.
  631.  
  632.        This flexible interpretation is intrinsically slower than
  633.        the indirect-only execution (like Forth), because of the
  634.        overhead of making the direct/indirect test.  In practical
  635.        implementations of RPL, it is possible to shift the overhead
  636.        almost entirely to the direct execution case, so that the
  637.        execution penalty for the indirect case is negligible,
  638.        including primitive assembly language objects that are never
  639.        executed directly.  The trick is to replace the last step of
  640.        the inner loop with the Forth-like PC = [O], and, for
  641.        prologues of directly-executable objects, replace the self-
  642.        address at the start of each prologue with a slice of
  643.        executable code delta in length. The compiled opcodes of
  644.        this slice must also be the address of a meta-prologue that
  645.        handles the direct execution case.  In Saturn CPU
  646.        implementations, the code slice consists of the instruction
  647.        M=M-1 (decrementing available memory is common to virtually
  648.        all directly-executable object prologues) plus a NOP
  649.        instruction to fill out the delta length.
  650.  
  651.        The virtue of direct execution is that it enables the
  652.        straightforward management of nameless objects that are
  653.        created during execution.  During the course of symbolic
  654.        algebraic manipulations, it is common to create, use, and
  655.        discard any number of temporary intermediate results; the
  656.  
  657.  
  658.  
  659.                                   Page 7
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.        necessity to compile and store these objects with some form
  667.        of name for indirect reference, then uncompile them to
  668.        recover memory, would make the whole process unmanageable.
  669.        In RPL such objects can be placed on the stack, copied,
  670.        embedded in composite objects, executed, and deleted.  For
  671.        example, a composite object representing the expression x +
  672.        y can be added to a second object representing 2z, returning
  673.        the result object x + y + 2z; furthermore, any of these
  674.        objects could be embedded in a program object to perform the
  675.        addition repetitively.
  676.  
  677.        Although RPL is primarily a syntax-less postfix language in
  678.        which procedures take their arguments from the stack and
  679.        return results to the stack, it does provide operations that
  680.        work on the runstream to provide for prefix operations and
  681.        for alterations to the normal threaded execution.  Foremost
  682.        among the runstream operations is the quoting operation that
  683.        takes the next object from the runstream and pushes it on
  684.        the data stack to postpone its execution.  This operation is
  685.        similar in purpose to the Lisp QUOTE, but takes its RPL name
  686.        ' (tick), from its Forth equivalent. RPL also has operations
  687.        to push and pop objects from the return stack.  (DO loop
  688.        parameters, however, are not stored on the return stack,
  689.        using a special environment instead.)
  690.  
  691.  
  692.        2.4.1  EVAL  An object on the data stack may be indirectly
  693.        executed by means of the RPL word EVAL, which pops an object
  694.        from the stack and executes its prolog.  The system object
  695.        EVAL should be distinguished from the user RPL command EVAL.
  696.        The latter is equivalent to system EVAL except for lists,
  697.        symbolic objects, and tagged objects.  For a tagged object,
  698.        user EVAL executes the object contained in the body of the
  699.        tagged object.  For lists and symbolics, user EVAL
  700.        dispatches to the system word COMPEVAL, which executes the
  701.        object as if it were a program (see below).
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.                                   Page 8
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.        2.4.2  Data_Class_Objects  Object types in this class are:
  733.               Binary Integer Object (note: the user RPL binary integer is actually
  734.                                      a hex string object in system RPL terms.)
  735.               Real Object
  736.               Extended Real Object
  737.               Complex Object
  738.               Extended Complex Object
  739.               Array Object
  740.               Linked Array Object
  741.               Character String Object
  742.               Hex String Object
  743.               Character Object
  744.               Graphics Object
  745.               Unit Object
  746.               List Object
  747.               Symbolic Object ("algebraic object")
  748.               Library Data Object
  749.               Directory Object
  750.               Tagged Object
  751.               External Object
  752.  
  753.        All objects in the data class have the property that, when
  754.        executed, they simply place themselves on the top of the
  755.        data stack.
  756.  
  757.  
  758.        2.4.3  Identifier_Class_Objects  Object types in this class
  759.        are:
  760.  
  761.               ROM Pointer Object (XLIB name)
  762.               Identifier Object (global name)
  763.               Temporary Identifier Object (local name)
  764.  
  765.        Objects in the identifier class share the property that they
  766.        serve to provide references for other objects. Identifier
  767.        objects represent the resolution of global variables, and
  768.        ROM Pointer Objects represent the resolution of commands
  769.        stored in libraries.  Temporary identifier objects, on the
  770.        other hand, provide references for temporary objects in
  771.        temporary environments.
  772.  
  773.        Execution of a ROM pointer object (by the DOROMP prologue)
  774.        entails locating and then executing the referenced ROM-WORD
  775.        object part. Non-location is an error condition.
  776.  
  777.        Execution of an identifier object (by the DOIDNT prologue)
  778.        entails locating and then executing the referenced global
  779.        variable object part. Non-location returns the identifier
  780.        object itself.
  781.  
  782.        Execution of a temporary identifier object (by the DOLAM
  783.        prologue), entails locating the referenced temporary object
  784.        and pushing it on the data stack.  Non-location is an error
  785.        condition.
  786.  
  787.  
  788.  
  789.  
  790.  
  791.                                   Page 9
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.        2.4.4  Procedure_Class_Objects  Object types in this class
  800.        are:
  801.  
  802.               Code Object
  803.               Primitive Code Object
  804.               Program Object
  805.  
  806.        Objects in the procedure class share the property of
  807.        executability, that is, executing a procedure class object
  808.        involves passing control to executable procedure or code
  809.        associated with the object.
  810.  
  811.        Code objects contain assembly language sequences for direct
  812.        execution by the CPU, but are otherwise normal, relocatable
  813.        objects.  Primitive code objects have no prolog in the usual
  814.        sense; the prolog address field points directly to the
  815.        object body, which contains an assembly language sequence.
  816.        These objects can only exist in permanent ROM, and can never
  817.        be executed directly.  When a code object or primitive code
  818.        object is executed, control is passed (by setting the PC) to
  819.        the machine language instruction set contained in the object
  820.        body. For a primitive code object, this control passing is
  821.        done by the execution mechanism (EVAL or the inner loop)
  822.        itself. For a code object, the prologue passes control by
  823.        placing the PC at the beginning of the machine language
  824.        slice contained in the object body. Note again that a
  825.        primitive code object prologue (which is its body) need not
  826.        contain logic to test for direct verses indirect execution
  827.        (nor contain code to update I or O) since, by definition, it
  828.        is never executed directly.
  829.  
  830.        Execution of a program is sequential execution of the
  831.        objects and object pointers that comprise the body of the
  832.        program.  The execution is threaded in that the objects in a
  833.        program may themselves be secondaries or pointers to
  834.        secondaries.  When encountered by the inner loop, an
  835.        embedded program is executed prior to resumption of
  836.        execution of the current one.
  837.  
  838.        The end of a program is marked by the object SEMI (from
  839.        "semicolon"--a ";" is the closing delimiter recognized by
  840.        the RPL compiler to mark the end of a program definition).
  841.        Execution of SEMI pops the top object pointer from the
  842.        return stack and resumes execution at that point.
  843.  
  844.  
  845.        2.4.5  Object_Skipover_and_SEMI  One of the basic premises
  846.        of RPL is that any RPL object that can be directly executed
  847.        (which includes all object types except primitive code
  848.        objects) must be traversable, that is, must have a structure
  849.        which allows it to be skipped over. Object skipover occurs
  850.        throughout the RPL system but most notably during direct
  851.        execution by the inner loop when the interpreter pointer I
  852.        must be set to point to the next object after the one being
  853.        directly executed.
  854.  
  855.  
  856.  
  857.                                  Page 10
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.        There exist both RPL objects and utilities to perform this
  865.        object skipover function. In addition, objects are required
  866.        to skipover themselves when being executed directly. The
  867.        skipover mechanism for atomic objects is simple and
  868.        straightforward since the object length is either known or
  869.        is easily computable.  For the composite objects (program,
  870.        list, unit, symbolic) the length is not easily computable
  871.        and the skipover function here is somewhat more involved,
  872.        using an implicit recursion.  These composite objects do not
  873.        carry known or easily computable length information and
  874.        therefore must have a tail delimiter, namely an object
  875.        pointer to the primitive code object SEMI. Note that SEMI
  876.        serves an explicit function for the program object (the
  877.        procedure class composite object); for data class composite
  878.        objects (list, unit, and symbolic objects), it only serves
  879.        as a tail delimiter.
  880.  
  881.  
  882.        2.4.6  RPL_Pointers  A pointer is defined to be an address
  883.        and may be either a location pointer or an object pointer. A
  884.        location pointer addresses any segment of the memory map
  885.        while an object pointer specifically addresses an object.
  886.        Note that, for example, the prologue address part of an
  887.        object is a location pointer.
  888.  
  889.  
  890.        2.5  Memory Management
  891.  
  892.        The uniformity of direct and indirect execution means not
  893.        only that objects as well as object pointers can be embedded
  894.        in the execution stream, but also that object pointers can
  895.        logically replace objects.  In particular, the RPL data and
  896.        return stacks explicitly are stacks of object pointers.
  897.        This means, for example, that an object on the data stack
  898.        can be copied (e.g. by DUP) at a cost of only delta bytes of
  899.        memory, regardless of the size of the object.  Furthermore,
  900.        duplication and similar stack operations are very fast.
  901.  
  902.        Of course, the objects referenced on the stacks must exist
  903.        somewhere in memory.  Many, including all of the system
  904.        objects that provide system management and an application
  905.        language, are defined in ROM and can be referenced by a
  906.        pointer with no other housekeeping implications.  Objects
  907.        created in RAM may exist in two places.  Those that are
  908.        unnamed are stored in a temporary object area, where each is
  909.        maintained as long as it is referenced by a pointer anywhere
  910.        in the system (this implies that if a temporary object
  911.        moves, all pointers to it must be updated).  Naming an
  912.        object consists of storing it as a pair with a name field in
  913.        a linked-list called the user object area.  These objects
  914.        are maintained indefinitely, until they are explicitly
  915.        purged or replaced.  A named object is accessed by means of
  916.        an identifier object, which consists of an object with a
  917.        name field as its body.  Executing an identifier causes the
  918.        user object area to be searched for an object stored with
  919.        the same name, which is then executed.  This run-time
  920.  
  921.  
  922.  
  923.                                  Page 11
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.        resolution is intrinsically slower than the compile-time
  931.        resolution used for ROM objects, but it allows for a dynamic
  932.        and flexible system where the order in which objects are
  933.        compiled is immaterial.
  934.  
  935.        The process of naming objects by storing them with names in
  936.        the user object area is augmented by the existence of local
  937.        environments, in which objects can be bound to names (lambda
  938.        variables) that are local to a currently executing
  939.        procedure.  The binding is abandoned when the procedure
  940.        completes execution.  This feature simpifies complicated
  941.        stack manipulations by allowing the stack objects to be
  942.        named and then referenced by name within the scope of a
  943.        defining procedure.
  944.  
  945.        RPL provides that any object stored in the user object area
  946.        can be deleted without corrupting anything in the system.
  947.        This requires certain design conventions:
  948.  
  949.           + When a RAM object is stored in the user object area, a
  950.             new copy of the object is stored, not a pointer to the
  951.             object.
  952.  
  953.           + Pointers to RAM objects are not permitted in composite
  954.             objects.  When a composite object is created from stack
  955.             objects, RAM objects are copied and directly embedded
  956.             in the composite.  When a stored object is represented
  957.             by name in a composite, it is the identifier object
  958.             that is embedded, not a location pointer as in Forth.
  959.  
  960.           + If a stored object is referenced by any pointers on the
  961.             stacks at the time when it is purged, it is copied to
  962.             the temporary object area and the pointers to it are
  963.             updated accordingly.  This means that the memory
  964.             associated with an object is not recovered until the
  965.             last reference to it is deleted.
  966.  
  967.        The use of temporary objects with multiple references means
  968.        that a temporary object can not necessarily be deleted from
  969.        memory immediately when a single reference to it is
  970.        eliminated.  In current RPL implementations, no memory
  971.        recovery at all is performed until the system runs out of
  972.        memory (M=0), at which time all unreferenced objects in the
  973.        temporary object area are deleted.  The process, called
  974.        "garbage collection" can be significantly time-consuming, so
  975.        that RPL execution does not proceed uniformly.
  976.  
  977.        From the preceding discussion, it will be apparent that RPL
  978.        is not as fast in general as Forth because of its extra
  979.        interpretation overhead and greatly elaborated memory
  980.        management scheme.  While maximum execution speed is always
  981.        desirable, the design of RPL emphasizes its role as an
  982.        interactive mathematical control language in which
  983.        flexibility, ease of use, and the ability to manipulate
  984.        procedural information are paramount.  In many cases, these
  985.        attributes of RPL result in faster problem-solving
  986.  
  987.  
  988.  
  989.                                  Page 12
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.        throughput than Forth, which executes faster but is more
  997.        difficult to program.
  998.  
  999.        RPL also provides for objects that are intermediate between
  1000.        those fixed in ROM and those that are mobile in RAM.  A
  1001.        library is a collection of objects, organized in a permanent
  1002.        structure that permits parse-time and run-time resolution by
  1003.        means of tables included in the library.  An XLIB name is an
  1004.        identifier class object that contains a library number and
  1005.        an object number within the library.  Execution of an XLIB
  1006.        name executes the stored object.  The identities and
  1007.        locations of libraries are determined at system
  1008.        configuration.  A particular library can be associated with
  1009.        its own RAM directory, so that, for example, a library might
  1010.        contain permanent formulas for which the variable values are
  1011.        maintained in RAM.
  1012.  
  1013.  
  1014.        2.6  User RPL and System RPL
  1015.  
  1016.        There is no fundamental difference between the HP 48
  1017.        programming language, which we will call "user RPL," and the
  1018.        "system RPL" in which HP 48 functionality is implemented.
  1019.        User language programs are executed by the same inner loop
  1020.        interpreter as system programs, with the same return stack.
  1021.        The data stack displayed on the HP 48 is the same as that
  1022.        used by system programs.  The distinction between user RPL
  1023.        and system RPL is only one of scope: user RPL is a subset of
  1024.        system RPL.  User RPL does not provide direct access to all
  1025.        of the data class object types that are available; the use
  1026.        of built-in procedures is limited to those that are provided
  1027.        as commands.
  1028.  
  1029.        A "command" is procedure-class object stored in a library,
  1030.        along with a text string that serves as the command's name.
  1031.        The name is used for compiling and decompiling the object.
  1032.        When the command line parser matches text in the command
  1033.        line with a command name, it compiles an object pointer if
  1034.        the command is contained in a library in the HP 48's
  1035.        permanent ROM.  Otherwise it compiles the corresponding XLIB
  1036.        name.  Also, built-in command objects are preceded in ROM by
  1037.        a six-nibble field that is the body of an XLIB name.  When
  1038.        the decompiler encounters an object pointer, it looks for
  1039.        this field in the ROM ahead of the object; if it finds a
  1040.        valid field, it then uses the information there to locate a
  1041.        text command name to display. Otherwise, it decompiles the
  1042.        object itself.
  1043.  
  1044.        Commands are distinguished from other procedure objects by
  1045.        certain conventions in their design.  Structurally, all
  1046.        commands are program objects, the first object in which is
  1047.        one of the system dispatch objects CK0, CK1&Dispatch,
  1048.        CK2&Dispatch, CK3&Dispatch, CK4&Dispatch, and CK5&Dispatch
  1049.        (see section 13).  CK0, which is used by zero-argument
  1050.        commands, may be followed by any additional objects.
  1051.        CK1&Dispatch ... CK&Dispatch must be followed by a sequence
  1052.  
  1053.  
  1054.  
  1055.                                  Page 13
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.        of pairs of objects; the first of each pair identifies a
  1063.        stack argument type combination, and the second specifies
  1064.        the object to execute for each corresponding combination.
  1065.        The last pair is followed by the end-program marker object
  1066.        (SEMI).
  1067.  
  1068.        The other command object conventions govern their behavior.
  1069.        In particular, they should:
  1070.  
  1071.        * remove any temporary objects from the stack, returning
  1072.        only the specified results;
  1073.  
  1074.        * do any range checking necessary to ensure that errors do
  1075.        not occur that might cause disasters;
  1076.  
  1077.        * restore HP48 modes to their original states, unless the
  1078.        command is specifically for changing a mode.
  1079.  
  1080.        The overhead involved in these structure and behavior
  1081.        conventions does impose a minor performance penalty.
  1082.        However, the primary execution speed advantage of system RPL
  1083.        over user RPL comes simply from the larger set of available
  1084.        procedures in system RPL, access to fast binary arithmetic,
  1085.        and improved control over system resources and execution
  1086.        flow.
  1087.  
  1088.  
  1089.        2.7  Programming in System RPL
  1090.  
  1091.        Writing programs in system RPL is no different in principle
  1092.        than in user RPL; the difference lies in the syntax and
  1093.        scope of the compiler.  For user RPL, the compiler is the
  1094.        command line ENTER, the logic of which is documented in the
  1095.        owners' manuals.  For system RPL developed on a PC, the
  1096.        compiler has several parts.  The immediate analog of the
  1097.        command line parser is the program RPLCOMP, which parses
  1098.        source code text into Saturn assembly language.  (The syntax
  1099.        used by RPLCOMP is described in xxx.) The output of RPLCOMP
  1100.        is passed to the assembler program SASM, which produces
  1101.        assembled object code.  The program SLOAD resolves symbol
  1102.        references in SASM's output, finally returning executable
  1103.        code suitable for downloading into the HP 48.  Individual
  1104.        objects can be collected in an HP 48 directory that is
  1105.        transferred back to the PC, where the program USRLIB can
  1106.        transform the directory into a library object.  (It would be
  1107.        desirable to create a library directly on the PC, but the
  1108.        program to do this is not available at present.)
  1109.  
  1110.        For the purpose of illustration, consider a hypothetical
  1111.        project development process that will result in a library
  1112.        object constructed with the USRLIB tool.  The library is to
  1113.        contain a single command, BASKET, which calculates basket
  1114.        weaving factors according to several input parameters.
  1115.        BASKET should be designed with the structure described above
  1116.        for commands.  In addition, assume that BASKET calls several
  1117.        other programs which are not to be user-accessible.  To
  1118.  
  1119.  
  1120.  
  1121.                                  Page 14
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.        achieve this, the objects are compiled on the PC, then
  1129.        downloaded into the HP 48 in a common directory, stored as
  1130.        BASKET, B1, B2, ... , where the latter variables contain the
  1131.        subroutines.  The directory is uploaded to the PC, where
  1132.        USRLIB is applied to it with the directive that B1, B2, ...
  1133.        are to be "hidden."
  1134.  
  1135.        There is no requirement that a program produced with the RPL
  1136.        compiler must be presented in a library object - if the
  1137.        entire application can be written within a single program,
  1138.        then so much the better.  As programs grow beyond some
  1139.        reasonable level of complexity, this becomes more difficult,
  1140.        and a library object approach with multiple variables
  1141.        becomes easier to manage.
  1142.  
  1143.  
  1144.          1.  Create the source file on the PC using your favorite
  1145.              editor.  The program source file name should have a
  1146.              ".s" extension, such as "prog.s". Use the compiler
  1147.              RPLCOMP.EXE to produce the Saturn assembler source
  1148.              file "prog.a".
  1149.  
  1150.          2.  Use the Saturn assembler SASM.EXE to assemble the
  1151.              program and produce an output file "prog.o".
  1152.  
  1153.          3.  Use the Saturn loader SLOAD.EXE to resolve your
  1154.              program's calls to HP 48 operating system.  SLOAD.EXE
  1155.              output files may have any name, but the ".ol"
  1156.              extension is often used.
  1157.  
  1158.          4.  Download the final file (use binary transfer!) to the
  1159.              HP 48, and try out your code.
  1160.  
  1161.          5.  Upload the directory containing one or more objects to
  1162.              the PC, and use USRLIB.EXE to convert it to a library.
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.                                  Page 15
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.        2.8  Sample RPL Program
  1195.  
  1196.  
  1197.        To get acquainted with the process of producing a program
  1198.        written in internal RPL, consider the following example,
  1199.        which we'll call TOSET.
  1200.  
  1201.  
  1202.        2.8.1  The_Source_File
  1203.  
  1204.        This program removes duplicate objects from a list by
  1205.        decomposing the list into a series of objects on the stack,
  1206.        creating a new empty list, and putting the stack objects
  1207.        into the new list if they're unique.
  1208.  
  1209.        * ( {list} --> {list}' )
  1210.        ASSEMBLE
  1211.                NIBASC  /HPHP48-D/
  1212.        RPL
  1213.        ::
  1214.          CK1NOLASTWD                   ( *Req. 1 argument* )
  1215.          CK&DISPATCH0 list
  1216.            ::
  1217.              DUPNULL{}? ?SEMI          ( *Exit for empty list* )
  1218.              INNERCOMP                 ( objn ... obj1 #n )
  1219.              reversym                  ( obj1 ... objn #n )
  1220.              NULL{} SWAP               ( obj1 ... objn {} #n )
  1221.              ZERO_DO (DO)
  1222.                SWAP                    ( obj1 ... objn-1 {} objn )
  1223.                apndvarlst              ( obj1 ... objn-1 {}' )
  1224.              LOOP
  1225.           ;
  1226.        ;
  1227.  
  1228.  
  1229.        The first line is a comment, showing the input and output
  1230.        conditions for the program.  Comments are denoted by an
  1231.        asterisk (*) in the first column, or within parentheses.
  1232.        Every programmer has their own style for comments. The style
  1233.        shown here is that objects are shown with stack level one on
  1234.        the right.  Text is enclosed in asterisks.
  1235.  
  1236.        The sequence
  1237.  
  1238.        ASSEMBLE
  1239.                NIBASC  /HPHP48-D/
  1240.        RPL
  1241.  
  1242.        is a command to the assembler that includes the header for
  1243.        binary data transfer from the PC to the HP48.  This is
  1244.        included here for simplicity, but could be included from
  1245.        another file by the loader.
  1246.  
  1247.        The first command, CK1NOLASTWD, requires the stack contain
  1248.        at least one item, and clears the ram location which stores
  1249.        the name of the current command.  This is important, because
  1250.  
  1251.  
  1252.  
  1253.                                  Page 16
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.        you don't want to attribute errors encountered in this
  1261.        program to the last function that generated an error.
  1262.  
  1263.        The second command, CK&DISPATCH0, reads a structure of the
  1264.        form
  1265.  
  1266.                type action
  1267.                type action
  1268.                ...
  1269.  
  1270.        to decide what action to take based on the TYPE of object
  1271.        presented.  If the type of object in level 1 does not have
  1272.        an entry in the table, the error "Bad Argument Type" will be
  1273.        generated.  In this example, only one type of argument, a
  1274.        list, is acceptable, and the corresponding action is a
  1275.        secondary.  For more on argument checking commands, see the
  1276.        chapter "Argument Validation".
  1277.  
  1278.        The command DUPNULL{}? returns the list and a TRUE/FALSE
  1279.        flag which indicates if the list is empty.  The command
  1280.        ?SEMI exits the secondary if the flag is TRUE.
  1281.  
  1282.        The command INNERCOMP is an internal form of the user word
  1283.        LIST->.  The number of objects is returned in level one as a
  1284.        binary integer (see the chapter "Binary Integers").
  1285.  
  1286.        The command "reversym" reverses the order of #n objects on
  1287.        the stack.  This is used here to account for the ordering of
  1288.        objects placed in a list by the "apndvarlst" which is
  1289.        described below.
  1290.  
  1291.        The ZERO_DO command begins a counted loop. This loop will
  1292.        process each object in the original list.  The (DO) command
  1293.        tells RPLCOMP that this is the start of a loop, otherwise
  1294.        the LOOP command would be flagged as unmatched.
  1295.  
  1296.        The "apndvarlst" command appends an object to a list if and
  1297.        only if that object does not appear in the list already.
  1298.  
  1299.        The LOOP command ends the loop.  For more on loop commands,
  1300.        see the chapter "Loop Structures".
  1301.  
  1302.  
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.                                  Page 17
  1320.  
  1321.  
  1322.  
  1323.  
  1324.        2.8.2  Compiling_the_Program  To compile the program for the
  1325.        HP 48, follow these steps:
  1326.  
  1327.          1.  Store the example code in a file TOSET.S.
  1328.  
  1329.          2.  RPLCOMP TOSET.S TOSET.A
  1330.  
  1331.              This command compiles the RPL source and produces a
  1332.              Saturn assembler source file.
  1333.  
  1334.          3.  SASM TOSET.A
  1335.  
  1336.              This command assembles the Saturn source file to
  1337.              produce the files TOSET.L and TOSET.O.
  1338.  
  1339.  
  1340.          4.  The file TOSET.M is a loader control file that looks
  1341.              like this:
  1342.  
  1343.              TITLE Example           <-- Specifies a listing title
  1344.              OUTPUT TOSET            <-- Specifies the output file
  1345.              LLIST TOSET.LR          <-- Specifies the listing file
  1346.              SUPPRESS XREF           <-- Suppresses the cross ref
  1347.              SEARCH ENTRIES.O        <-- Reads HP48 entries
  1348.              REL TOSET.O             <-- Loads TOSET.o
  1349.              END
  1350.  
  1351.              Create the file TOSET.M and invoke the loader:
  1352.  
  1353.              SLOAD -H TOSET.M
  1354.  
  1355.        Check the file TOSET.LR for errors. An unresolved reference
  1356.        usually points to a misspelled command.  Now download the
  1357.        file TOSET into the HP 48 and give it a try!
  1358.  
  1359.        Enter the list { 1 2 2 3 3 3 4 }, evaluate TOSET, and you
  1360.        should get { 1 2 3 4 }.
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.  
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.                                  Page 18
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.        3.  Object Structures
  1393.  
  1394.  
  1395.        This chapter provides additional information about some of
  1396.        the RPL object types supported by the HP 48.  Although the
  1397.        information is primarily relevant to assembly language
  1398.        programming, a knowledge of object structure can often help
  1399.        in understanding performance and efficiency issues in RPL
  1400.        programming.
  1401.  
  1402.        Unless explicitly stated otherwise, all specifically-defined
  1403.        fields within an object body are assumed to be 5 nibbles,
  1404.        the CPU address width.
  1405.  
  1406.  
  1407.        3.1  Object Types
  1408.  
  1409.        3.1.1  Identifier_Object
  1410.  
  1411.        An identifier object is atomic, has the prologue DOIDNT, and
  1412.        a body which is an ID Name form.
  1413.  
  1414.                    +---------------+
  1415.                    |  -> DOIDNT    |  Prologue Address
  1416.                    +---------------+                     Identifier
  1417.                    | ID NAME FORM  |  Body               Object
  1418.                    +---------------+
  1419.  
  1420.        An ID name form is a character sequence preceded by a one-
  1421.        byte character count field.
  1422.  
  1423.        Identifier objects are, among other things, the compiletime
  1424.        resolution of global variables.
  1425.  
  1426.  
  1427.        3.1.2  Temporary_Identifier_Object
  1428.  
  1429.        A temporary identifier object is atomic, has the prologue
  1430.        DOLAM, and a body which is an ID name form.
  1431.  
  1432.                    +---------------+
  1433.                    |  -> DOLAM     | Prologue Address    Temporary
  1434.                    +---------------+                     Identifier
  1435.                    |  ID NAME FORM | Body                Object
  1436.                    +---------------+
  1437.  
  1438.        Temporary identifier objects provide named references for
  1439.        temporary objects bound to the identifiers in the formal
  1440.        parameter list of a temporary variable structure.
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.                                  Page 19
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457.  
  1458.        3.1.3  ROM_Pointer_Object
  1459.  
  1460.        A ROM pointer object, or XLIB name, is atomic, has the
  1461.        prologue DOROMP, and a body which is a ROM-WORD identifier.
  1462.  
  1463.                    +------------------+
  1464.                    |   -> DOROMP      | Prologue Address
  1465.                    +------------------+                     ROM
  1466.                    |                  |                     Pointer
  1467.                    |    Command       | Body                Object
  1468.                    |   Identifier     |
  1469.                    |                  |
  1470.                    +------------------+
  1471.  
  1472.        ROM pointer objects are the compiletime resolution of
  1473.        commands in mobile libraries.  A command indentifier
  1474.        identifier is a pair of 12 bit fields: the first field is a
  1475.        library ID number, and the second field is the command ID
  1476.        number within the library.
  1477.  
  1478.  
  1479.        3.1.4  Binary_Integer_Object
  1480.  
  1481.        A binary integer object is atomic, has the prologue DOBINT,
  1482.        and a body which is a 5-nibble number.
  1483.  
  1484.                    +------------------+
  1485.                    |   -> DOBINT      | Prologue Address
  1486.                    +------------------+
  1487.                    |                  |             Binary
  1488.                    |      Number      | Body        Integer
  1489.                    |                  |             Object
  1490.                    +------------------+
  1491.  
  1492.        The use of this object type is to represent binary integers
  1493.        whose precision is equivalent to a memory address.
  1494.  
  1495.  
  1496.        3.1.5  Real_Number_Object
  1497.  
  1498.        A real number object is atomic, has the prologue DOREAL, and
  1499.        a body which is a single-precision floating point number (or
  1500.        real number, for short).
  1501.  
  1502.                    +-----------------+
  1503.                    |  -> DOREAL      | Prologue Address
  1504.                    +-----------------+
  1505.                    |                 |
  1506.                    | Single-precision|            Real Number
  1507.                    | Floating Point  | Body       Object
  1508.                    | Number          |
  1509.                    |                 |
  1510.                    +-----------------+
  1511.  
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517.                                  Page 20
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.        One use of this object type is to represent packed
  1525.        floating-point numbers (eight bytes) on a Saturn system and,
  1526.        in this application, the body of the object may consist of
  1527.        16 BCD nibbles as follows:
  1528.  
  1529.               (low mem)      EEEMMMMMMMMMMMMMMMS
  1530.  
  1531.        where S is the numeric sign (0 for nonnegative and 9 for
  1532.        negative), MMMMMMMMMMMM is a 12 digit mantissa with an
  1533.        implied decimal point between the first and second digits
  1534.        and the first digit nonzero if the number is nonzero, and
  1535.        EEE the exponent in tens complement form (-500 < EEE < 500).
  1536.  
  1537.  
  1538.        3.1.6  Extended_Real_Number_Object
  1539.  
  1540.        An extended real number object is atomic, has the prologue
  1541.        DOEREL, and a body which is an extended-precision floating
  1542.        point number (or extended real, for short).
  1543.  
  1544.                    +-----------------+
  1545.                    |  -> DOEREL      | Prologue Address
  1546.                    +-----------------+
  1547.                    |                 |              Extended
  1548.                    | Extended-       |              Real Number
  1549.                    | precision       |              Object
  1550.                    | Floating Point  | Body
  1551.                    | Number          |
  1552.                    |                 |
  1553.                    +-----------------+
  1554.  
  1555.        One use of this object type is to represent unpacked
  1556.        floating-point numbers (10.5 bytes) on a Saturn system and,
  1557.        in this application, the body of the object may consist of
  1558.        21 BCD nibbles as follows:
  1559.  
  1560.              (low mem)     EEEEEMMMMMMMMMMMMMMMS
  1561.  
  1562.        where S is the numeric sign (0 for nonnegative, 9 for
  1563.        negative), MMMMMMMMMMMMMMM is a 15 digit mantissa with an
  1564.        implied decimal point between the first and second digits
  1565.        and the first digit nonzero if the number is nonzero, and
  1566.        EEEEE the exponent in tens complement form (-50000 < EEEEE <
  1567.        50000).
  1568.  
  1569.  
  1570.  
  1571.  
  1572.  
  1573.  
  1574.  
  1575.  
  1576.  
  1577.  
  1578.  
  1579.  
  1580.  
  1581.  
  1582.  
  1583.                                  Page 21
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.        3.1.7  Complex_Number_Object
  1591.  
  1592.        A complex number object is atomic, has the prologue DOCMP,
  1593.        and a body which is a pair of real numbers.
  1594.  
  1595.                    +------------------+
  1596.                    |    -> DOCMP      | Prologue Address
  1597.                    +------------------+
  1598.                    |                  |            Complex
  1599.                    |   Real Number    |            Object
  1600.                    |    ---------     | Body
  1601.                    |   Real Number    |
  1602.                    |                  |
  1603.                    +------------------+
  1604.  
  1605.        The use of this object type is to represent single-precision
  1606.        complex numbers, where the real part is interpreted as the
  1607.        first real number in the pair.
  1608.  
  1609.  
  1610.        3.1.8  Extended_Complex_Number_Object
  1611.  
  1612.        An extended complex number object is atomic, has the
  1613.        prologue DOECMP, and a body which is a pair of extended real
  1614.        numbers.
  1615.  
  1616.                    +------------------+
  1617.                    |    -> DOECMP     | Prologue Address
  1618.                    +------------------+
  1619.                    |                  |
  1620.                    |  Extended Real   |
  1621.                    |     Number       |              Extended
  1622.                    |    ----------    | Body         Complex Number
  1623.                    |  Extended Real   |              Object
  1624.                    |     Number       |
  1625.                    |                  |
  1626.                    +------------------+
  1627.  
  1628.        The use of this object type is to represent extended-
  1629.        precision complex numbers in the same way as for the complex
  1630.        object.
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.                                  Page 22
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.        3.1.9  Array_Object
  1657.  
  1658.        An array object is atomic, has the prologue DOARRY, and a
  1659.        body which is a collection of the array elements. The body
  1660.        also includes a length field (indicating the length of the
  1661.        body), a type indicator (indicating the object type of its
  1662.        elements), a dimension count field, and length fields for
  1663.        each dimension.
  1664.  
  1665.                    +------------------+
  1666.                    |  -> DOARRY       | Prologue Address
  1667.                    +------------------+
  1668.                    |                  |
  1669.                    |  Length Field    |
  1670.                    |   ------------   |
  1671.                    | Type Indicator   |
  1672.                    |   ------------   |
  1673.                    | Dimension Count  |
  1674.                    |   ------------   |
  1675.                    |Dimension 1 Length|
  1676.                    |   ------------   |
  1677.                    |Dimension 2 Length|
  1678.                    |   ------------   |
  1679.                    |        .         |             Array
  1680.                    |        .         |             Object
  1681.                    |        .         | Body
  1682.                    |   ------------   |
  1683.                    |Dimension N Length|
  1684.                    |   ------------   |
  1685.                    |                  |
  1686.                    |    Elements      |
  1687.                    |                  |
  1688.                    +------------------+
  1689.  
  1690.        The array elements are object bodies of the same object
  1691.        type.  The type indicator is a prologue address (think of
  1692.        this prologue address as applying to each element of the
  1693.        array).
  1694.  
  1695.        Array "OPTION BASE" is always 1. A null array is designated
  1696.        by any dim limit having the value zero. All elements of an
  1697.        array object are always present as indicated by the
  1698.        dimensionality information and are ordered in memory by the
  1699.        lexicographic order of the array's indices.
  1700.  
  1701.  
  1702.        3.1.10  Linked_Array_Object
  1703.  
  1704.        A linked array object is atomic, has the prologue DOLNKARRY,
  1705.        and a body which is a collection of the array elements. The
  1706.        body also includes a length field (indicating the length of
  1707.        the body), a type indicator (indicating the object type of
  1708.        its elements), a dimension count field, length fields for
  1709.        each dimension, and a pointer table whose contents are
  1710.        forward self-relative offsets to the array elements; the
  1711.        elements of the pointer table are ordered in memory by the
  1712.  
  1713.  
  1714.  
  1715.                                  Page 23
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.        lexicographic order of the array's indices.
  1723.  
  1724.                    +------------------+
  1725.                    | -> DOLNKARRY     | Prologue Address
  1726.                    +------------------+
  1727.                    |                  |
  1728.                    |  Length Field    |
  1729.                    |   ------------   |
  1730.                    | Type Indicator   |
  1731.                    |   ------------   |
  1732.                    | Dimension Count  |
  1733.                    |   ------------   |
  1734.                    |Dimension 1 Length|
  1735.                    |   ------------   |
  1736.                    |Dimension 2 Length|
  1737.                    |   ------------   |             Linked
  1738.                    |        .         |             Array
  1739.                    |        .         |             Object
  1740.                    |        .         | Body
  1741.                    |   ------------   |
  1742.                    |Dimension N Length|
  1743.                    |   ------------   |
  1744.                    |                  |
  1745.                    |  Pointer Table   |
  1746.                    |                  |
  1747.                    |   ------------   |
  1748.                    |                  |
  1749.                    |    Elements      |
  1750.                    |                  |
  1751.                    +------------------+
  1752.  
  1753.        The array elements are object bodies of the same object
  1754.        type.  The type indicator is a prologue address (think of
  1755.        this prologue address as applying to each element of the
  1756.        array).
  1757.  
  1758.        Linked array "OPTION BASE" is always 1. A null linked array
  1759.        is designated by any dim limit having the value zero.  There
  1760.        is no assumption on the ordering of the elements of a linked
  1761.        array object, nor on their presence; absence of an element
  1762.        lying on an allocated dimension is indicated by the value
  1763.        zero occupying the corresponding pointer table element.
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.                                  Page 24
  1782.  
  1783.  
  1784.  
  1785.  
  1786.        3.1.11  Character_String_Object
  1787.  
  1788.        A character string object is atomic, has the prologue
  1789.        DOCSTR, and a body which is a character string (a byte
  1790.        sequence). The body also includes a length field (indicating
  1791.        the length of the body).
  1792.  
  1793.                    +-------------------+
  1794.                    |  -> DOCSTR        | Prologue Address
  1795.                    +-------------------+
  1796.                    |                   |            Character
  1797.                    |   Length Field    |            String
  1798.                    |   ------------    | Body       Object
  1799.                    |   Byte Sequence   |
  1800.                    |                   |
  1801.                    +-------------------+
  1802.  
  1803.  
  1804.  
  1805.        3.1.12  Hex_String_Object
  1806.  
  1807.        A hex string object is atomic, has the prologue DOHSTR, and
  1808.        a body which is a nibble sequence. The body also includes a
  1809.        length field (indicating the length of the body).
  1810.  
  1811.                    +-------------------+
  1812.                    |  -> DOHSTR        | Prologue Address
  1813.                    +-------------------+
  1814.                    |                   |            Hex
  1815.                    |   Length Field    |            String
  1816.                    |   ------------    | Body       Object
  1817.                    |  Nibble Sequence  |
  1818.                    |                   |
  1819.                    +-------------------+
  1820.  
  1821.        A typical use for this object type is a buffer or table.
  1822.        Hex string objects of 16 nibbles or fewer are used to
  1823.        represent user RPL binary integer objects.
  1824.  
  1825.  
  1826.        3.1.13  Character_Object
  1827.  
  1828.        A character object is atomic, has the prologue DOCHAR, and a
  1829.        body which is a single byte.
  1830.  
  1831.                    +-------------------+
  1832.                    |    -> DOCHAR      | Prologue Address
  1833.                    +-------------------+
  1834.                    |                   |          Character
  1835.                    |        Byte       | Body     Object
  1836.                    |                   |
  1837.                    +-------------------+
  1838.  
  1839.        This object type is used to represent one-byte quantities,
  1840.        such as ASCII or ROMAN8 characters.
  1841.  
  1842.  
  1843.  
  1844.  
  1845.  
  1846.  
  1847.                                  Page 25
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.        3.1.14  Unit_Object
  1855.  
  1856.        A unit object is composite, has the prologue DOEXT, and
  1857.        a body which is a sequence consisting of a real number
  1858.        followed by unit name strings, prefix characters, unit
  1859.        operators, and real number powers, tail delimited by a
  1860.        pointer to SEMI.
  1861.  
  1862.                    +-------------------+
  1863.                    |    -> DOEXT       |
  1864.                    +-------------------+
  1865.                    |  Object Sequence  |
  1866.                    |                   |
  1867.                    |     ->SEMI        |
  1868.                    +-------------------+
  1869.  
  1870.  
  1871.  
  1872.        3.1.15  Code_Object
  1873.  
  1874.        A code object is atomic, has the prologue DOCODE, and a body
  1875.        which is an assembly language slice. The body also includes
  1876.        a length field (indicating the length of the body). When
  1877.        executed, the prologue places the system program counter at
  1878.        the assembly language slice within the body.
  1879.  
  1880.                    +--------------------+
  1881.                    |  -> DOCODE         | Prologue Address
  1882.                    +--------------------+
  1883.                    |                    |           Code Object
  1884.                    |   Length Field     |
  1885.                    |   ------------     | Body
  1886.                    | Assembly Language  |
  1887.                    |      Slice         |
  1888.                    |                    |
  1889.                    +--------------------+
  1890.  
  1891.        The major applications for this object type are assembly
  1892.        language procedures which can be directly embedded in
  1893.        composite objects or exist in RAM.
  1894.  
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.                                  Page 26
  1914.  
  1915.  
  1916.  
  1917.  
  1918.  
  1919.  
  1920.        3.1.16  Primitive_Code_Object
  1921.  
  1922.        A primitive code object is a special case of a code object,
  1923.        used to represent code primitives in built-in libraries.
  1924.        The prologue of a primitive code object is its body, which
  1925.        is an assembly language slice; thus, when executed, the body
  1926.        executes itself.
  1927.  
  1928.                    +------------------+
  1929.             +-----------------        | Prologue Address
  1930.             |      +------------------+
  1931.             +----->|                  |            Primitive
  1932.                    | Assembly Language| Body       Code Object
  1933.                    |      Slice       |
  1934.                    |                  |
  1935.                    +------------------+
  1936.  
  1937.        The primary purpose of this object type is more rapid
  1938.        execution of code objects in built-in libraries, that is,
  1939.        these objects are executed without the extra level inherent
  1940.        in separate prologue execution.  However, their structure
  1941.        implies that (1) they can only exist in built-in libraries
  1942.        (never in RAM or mobile libraries) since the body must exist
  1943.        at a fixed address, (2) they cannot be skipped, and (3) they
  1944.        cannot exist in any situation where traversal may be
  1945.        required, such as an element of an array or an object within
  1946.        any composite object.
  1947.  
  1948.        Note that this object type is an exception to the object
  1949.        type classification scheme presented at the beginning of
  1950.        this document. However, an object is a primitive code object
  1951.        if and only if the prologue address equals the object
  1952.        address plus 5. In addition, the prologues for this object
  1953.        type (that is, the object bodies) need not contain logic to
  1954.        test for direct verses indirect execution since, by
  1955.        definition, they cannot be executed directly.
  1956.  
  1957.  
  1958.        3.1.17  Program_Object
  1959.  
  1960.        A program object (secondary) is composite, has the prologue
  1961.        DOCOL, and a body which is a sequence of objects and object
  1962.        pointers, the last of which is an object pointer whose
  1963.        pointee is the primitive code object SEMI.
  1964.  
  1965.                    +------------------+
  1966.                    |  -> DOCOL        | Prologue Address
  1967.                    +------------------+
  1968.                    |                  |
  1969.                    |     Object/      |          Secondary
  1970.                    |  Object Pointer  |          Object
  1971.                    |    Sequence      |
  1972.                    |     --------     | Body
  1973.                    |     -> SEMI      |
  1974.                    |                  |
  1975.                    +------------------+
  1976.  
  1977.  
  1978.  
  1979.                                  Page 27
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.        3.1.18  List_Object
  1987.  
  1988.        A list object is composite, has the prologue DOLIST, and a
  1989.        body which is a sequence of objects and object pointers, the
  1990.        last of which is an object pointer whose pointee is the
  1991.        primitive code object SEMI.
  1992.  
  1993.                    +------------------+
  1994.                    |  -> DOLIST       | Prologue Address
  1995.                    +------------------+
  1996.                    |                  |
  1997.                    |     Object/      |          List
  1998.                    |  Object Pointer  |          Object
  1999.                    |    Sequence      |
  2000.                    |     --------     | Body
  2001.                    |     -> SEMI      |
  2002.                    |                  |
  2003.                    +------------------+
  2004.  
  2005.  
  2006.        3.1.19  Symbolic_Object
  2007.  
  2008.        A symbolic object is composite, has the prologue DOSYMB, and
  2009.        a body which is a sequence of objects and object pointers,
  2010.        the last of which is an object pointer whose pointee is the
  2011.        primitive code object SEMI.
  2012.  
  2013.                    +------------------+
  2014.                    |  -> DOSYMB       | Prologue Address
  2015.                    +------------------+
  2016.                    |                  |
  2017.                    |     Object/      |          Symbolic
  2018.                    |  Object Pointer  |          Object
  2019.                    |    Sequence      |
  2020.                    |     --------     | Body
  2021.                    |     -> SEMI      |
  2022.                    |                  |
  2023.                    +------------------+
  2024.  
  2025.        This object type is used to represent symbolic objects for
  2026.        symbolic math applications.
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.  
  2045.                                  Page 28
  2046.  
  2047.  
  2048.  
  2049.  
  2050.  
  2051.  
  2052.        3.1.20  Directory_Object
  2053.  
  2054.        A directory (RAMROMPAIR) object is atomic, has the prologue
  2055.        DORRP and a body which consists of a Library ID number and a
  2056.        RAMPART (linked list of variables--object/name pairs.
  2057.  
  2058.                    +----------------+
  2059.                    |  -> DORRP      |  Prologue Address
  2060.                    +----------------+
  2061.                    |                |           RAMROMPAIR
  2062.                    |  ROMPART ID    |           Object
  2063.                    |    --------    |  Body
  2064.                    |    RAMPART     |
  2065.                    +----------------+
  2066.  
  2067.  
  2068.  
  2069.        3.1.21  Graphics_Object
  2070.  
  2071.        A graphics object is atomic, has the prologue DOGROB and a
  2072.        body which consists of the following:
  2073.  
  2074.         + A 5 nibble length field for the data which follows.
  2075.  
  2076.         + A five nibble quantity that describes the height of the
  2077.           graphic in pixels.
  2078.  
  2079.         + A five nibble quantity that describes the width of the
  2080.           graphic in pixels.
  2081.  
  2082.         + The data.
  2083.  
  2084.        The actual row dimension in nibbles (W) is always even for
  2085.        hardware reasons, hence each row of pixel data is padded
  2086.        with anywhere from 0-7 bits of wasted data.
  2087.  
  2088.                    +----------------+
  2089.                    |  -> DOGROB     | Prologue Address
  2090.                    +----------------+
  2091.                    |    Len(nibs)   |
  2092.                    +----------------+
  2093.                    | Height (pixels)|         Graphics
  2094.                    +----------------+ Body    Object
  2095.                    | Width (pixels) |
  2096.                    +----------------+
  2097.                    |   Grob Data    |
  2098.                    |      ...       |
  2099.                    +----------------+
  2100.  
  2101.        The data nibbles begin at the upper-left corner of the
  2102.        graphics object and proceed left-to-right, top-to-bottom.
  2103.        Each row of pixel data is padded as needed to obtain an even
  2104.        number of nibbles per row. Thus the width in nibbles W is
  2105.        determined by:
  2106.  
  2107.                         W=CEIL(Width in pixels)/8
  2108.  
  2109.  
  2110.  
  2111.                                  Page 29
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.        The bits in each nibble are written in reverse order, so the
  2119.        leftmost displayed pixel in a nibble is represented by the
  2120.        least-significant bit of the nibble.
  2121.  
  2122.  
  2123.        3.2  Terminology and Abbreviations.
  2124.  
  2125.        In the stack diagrams used throughout the remainder of this
  2126.        document, the following symbols are used to represent the
  2127.        various object types:
  2128.  
  2129.        ob ........... Any object
  2130.        id ........... Identifier Object
  2131.        lam .......... Temporary Identifier Object
  2132.        romptr ....... ROM Pointer Object
  2133.        __# ............ Binary Integer Object
  2134.        % ............ Real Object
  2135.        %% ........... Extended Real Object
  2136.        C% ........... Complex Object
  2137.        C%% .......... Extended Complex Object
  2138.        arry ......... Array Object
  2139.        lnkarry ...... Linked Array Object
  2140.        $ ............ Character String Object
  2141.        hxs .......... Hex String Object
  2142.        chr .......... Character Object
  2143.        ext .......... External Object
  2144.        code ......... Code Object
  2145.        primcode ..... Primitive Code Object
  2146.        :: ........... Secondary Object
  2147.        {} ........... List Object
  2148.        symb ......... Symbolic Object
  2149.        comp ......... Any Composite Object (list, secondary, symbolic)
  2150.        rrp .......... Directory Object
  2151.        tagged ....... Tagged Object
  2152.        flag ......... TRUE/FALSE
  2153.  
  2154.        (TRUE and FALSE above denote the object parts of built-in
  2155.        ROM-WORDs having these names. The addresses of these objects
  2156.        (that is, their data stack representations) are interpreted
  2157.        by RPL control structures as the appropriate truth value.
  2158.        Both objects are primitive code objects which, when
  2159.        executed, place themselves on the data stack).
  2160.  
  2161.        In addition to the above notation, some additional
  2162.        terminology is useful.
  2163.  
  2164.        ELEMENT:
  2165.         An ELEMENT of a composite object is any object or object
  2166.         pointer in the body of the composite object.
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.  
  2174.  
  2175.  
  2176.  
  2177.                                  Page 30
  2178.  
  2179.  
  2180.  
  2181.  
  2182.  
  2183.  
  2184.        CORE:
  2185.         of a character string: the core of a character string
  2186.                                object is the character data in
  2187.                                the body.
  2188.  
  2189.         of a hex string: the core of a hex string object is the
  2190.                          nibble sequence in the body.
  2191.  
  2192.         of a composite: the core of a composite object is the
  2193.                         element sequence in the body not
  2194.                         including the trailing object pointer
  2195.                         to semi.
  2196.  
  2197.        LENGTH:
  2198.         of a character string: the length of a character string
  2199.                                object is the number of characters
  2200.                                in the core.
  2201.  
  2202.         of a hex string: the length of a hex string object is the
  2203.                          number of nibbles in the core.
  2204.  
  2205.         of a composite: the length of a composite object is the
  2206.                         number of elements in the core.
  2207.  
  2208.        NULL:
  2209.         character string: a null character string object is one
  2210.                           whose length is zero.
  2211.  
  2212.         hex string: a null hex string object is one whose length
  2213.                     is zero.
  2214.  
  2215.         composite: a null composite object is one whose length
  2216.                    is zero.
  2217.  
  2218.        INTERNAL:
  2219.         an internal of a composite object is any object in the
  2220.         core of the composite object or the pointee of any object
  2221.         pointer in the core of the composite object.
  2222.  
  2223.        (A composite object is often loosely referred to as
  2224.        containing a specific object type, for example "a list of
  2225.        binary integers"; what is meant is that the core internals
  2226.        are all of this object type).
  2227.  
  2228.  
  2229.  
  2230.  
  2231.  
  2232.  
  2233.  
  2234.  
  2235.  
  2236.  
  2237.  
  2238.  
  2239.  
  2240.  
  2241.  
  2242.  
  2243.                                  Page 31
  2244.  
  2245.  
  2246.  
  2247.  
  2248.        4.  Binary Integers
  2249.  
  2250.        Internal binary integers have a fixed size of 20 bits, and
  2251.        are the most often used type for counting, loops, etc.
  2252.        Binary integers offer advantages of size and speed.
  2253.  
  2254.        NOTE: User level binary integers are implemented as hex
  2255.              strings, so a user's object #247d is actually a hex
  2256.              string, and should not be confused with a binary
  2257.              integer whose prologue is DOBINT.
  2258.  
  2259.  
  2260.        4.1  Built-in Binary Integers
  2261.  
  2262.        The RPLCOMP compiler interprets a decimal number in a source
  2263.        file as a directive to produce a binary integer object -
  2264.        using a prologue and a body.  Built-in binary integers can
  2265.        be accessed with just an object pointer.  For instance, " 43
  2266.        " (no quotes) in the source file produces a binary object:
  2267.  
  2268.                CON(5)  =DOBINT
  2269.                CON(5)  43
  2270.  
  2271.        The object takes five bytes, but can be replaced by the word
  2272.        "FORTYTHREE", which is a supported entry point which would
  2273.        generate the following code:
  2274.  
  2275.                CON(5)  =FORTYTHREE
  2276.  
  2277.        One pitfall to be aware of in binary integer naming
  2278.        conventions is the difference between the entries FORTYFIVE
  2279.        and FOURFIVE.  In the former case, the value is decimal 45,
  2280.        but the latter is decimal 69.  Names like 2EXT and IDREAL,
  2281.        where the values are not obvious, are used in conjunction
  2282.        with the CK&Dispatch family of argument checking commands.
  2283.        The names for the CK&Dispatch family are equated to the same
  2284.        places as other bints.  This has been done for readability.
  2285.        For instance, the word SEVENTEEN, for decimal 17, has the
  2286.        names 2REAL and REALREAL equated to the same location.  A
  2287.        trailing "d" or "h" on a name such as BINT_122d or BINT80h
  2288.        indicates the base associated with the value.
  2289.  
  2290.        Words such as ONEONE, ZEROONE, etc. put more than one binary
  2291.        integer on the stack.  These are indicated by a tiny stack
  2292.        diagram in parentheses, such as (-->  #1 #1 ) for ONEONE.
  2293.  
  2294.  
  2295.  
  2296.  
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.  
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.  
  2309.                                  Page 32
  2310.  
  2311.  
  2312.  
  2313.  
  2314.  
  2315.  
  2316.        The supported entries for binary integers are listed below
  2317.        with the hex value in parentheses where needed:
  2318.  
  2319.        2EXT (#EE)       FORTYNINE        SYMREAL (#A1)
  2320.        2GROB (#CC)      FORTYONE         SYMSYM (#AA)
  2321.        2LIST (#55)      FORTYSEVEN       TAGGEDANY (#D0)
  2322.        2REAL (#11)      FORTYSIX         TEN
  2323.        3REAL (#111)     FORTYTHREE       THIRTEEN
  2324.        Attn# (#A03)     FORTYTWO         THIRTY
  2325.        BINT253          FOUR             THIRTYEIGHT
  2326.        BINT255d         FOURFIVE         THIRTYFIVE
  2327.        BINT40h          FOURTEEN         THIRTYFOUR
  2328.        BINT80h          FOURTHREE        THIRTYNINE
  2329.        BINTC0h          FOURTWO          THIRTYONE
  2330.        BINT_115d        FOURTY           THIRTYSEVEN
  2331.        BINT_116d        IDREAL (#61)     THIRTYSIX
  2332.        BINT_122d        INTEGER337       THIRTYTHREE
  2333.        BINT_130d        LISTCMP (#52)    THIRTYTWO
  2334.        BINT_131d        LISTLAM (#57)    THREE
  2335.        BINT_65d         LISTREAL (#51)   TWELVE
  2336.        BINT_91d         MINUSONE(#FFFFF) TWENTY
  2337.        BINT_96d         NINE             TWENTYEIGHT
  2338.        Connecting(#C0A) NINETEEN         TWENTYFIVE
  2339.        EIGHT            ONE              TWENTYFOUR
  2340.        EIGHTEEN         ONEHUNDRED       TWENTYNINE
  2341.        EIGHTY           ONEONE(--> #1 #1) TWENTYONE
  2342.        EIGHTYONE        REALEXT (#1E)    TWENTYSEVEN
  2343.        ELEVEN           REALOB (#10)     TWENTYSIX
  2344.        EXT (#E)         REALOBOB (#100)  TWENTYTHREE
  2345.        EXTOBOB (#E00)   REALREAL (#11)   TWENTYTWO
  2346.        EXTREAL (#E1)    REALSYM (#1A)    TWO
  2347.        EXTSYM  (#EA)    ROMPANY (#F0)    XHI
  2348.        FIFTEEN          SEVEN            XHI-1 (#82)
  2349.        FIFTY            SEVENTEEN        ZERO
  2350.        FIFTYEIGHT       SEVENTY          ZEROZERO (--> #0 #0 )
  2351.        FIFTYFIVE        SEVENTYFOUR    ZEROZEROONE (--> #0 #0 #1 )
  2352.        FIFTYFOUR        SEVENTYNINE   ZEROZEROTWO (--> #0 #0 #2 )
  2353.        FIFTYNINE        SIX          ZEROZEROZERO (--> #0 #0 #0 )
  2354.        FIFTYONE         SIXTEEN          char (#6F)
  2355.        FIFTYSEVEN       SIXTY            id (#6)
  2356.        FIFTYSIX         SIXTYEIGHT       idnt (#6)
  2357.        FIFTYTHREE       SIXTYFOUR        infreserr (#305)
  2358.        FIFTYTWO         SIXTYONE         intrptderr (#a03)
  2359.        FIVE             SIXTYTHREE       list (#5)
  2360.        FIVEFOUR         SIXTYTWO         ofloerr (#303)
  2361.        FIVESIX          SYMBUNIT (#9E)   real (#1)
  2362.        FIVETHREE        SYMEXT (#AE)     seco (#8)
  2363.        FORTY            SYMID (#A6)      str (#3)
  2364.        FORTYEIGHT       SYMLAM (#A7)     sym (#A)
  2365.        FORTYFIVE        SYMOB (#A0)      symb (#9)
  2366.        FORTYFOUR
  2367.  
  2368.  
  2369.  
  2370.  
  2371.  
  2372.  
  2373.  
  2374.  
  2375.                                  Page 33
  2376.  
  2377.  
  2378.  
  2379.  
  2380.        4.2  Binary Integer Manipulation
  2381.  
  2382.        4.2.1  Arithmetic_Functions
  2383.  
  2384.        #*              ( #2 #1 --> #2*#1 )
  2385.        #+              ( #2 #1 --> #2+#1 )
  2386.        #+-1            ( #2 #1 --> #2+#1-1 )
  2387.        #-              ( #2 #1 --> #2-#1 )
  2388.        #-#2/           ( #2 #1 --> (#2-#1)/2 )
  2389.        #-+1            ( #2 #1 --> (#2-#1)+1 )
  2390.        #/              ( #2 #1 --> #remainder #quotient )
  2391.        #1+             ( # --> #+1 )
  2392.        #1+'            ( # --> #+1 and quotes next runstream object
  2393.        #1+DUP          ( # --> #+1 #+1 )
  2394.        #1-             ( # --> #-1 )
  2395.        #10*            ( # --> #*10 )
  2396.        #10+            ( # --> #+10 )
  2397.        #12+            ( # --> #+12 )
  2398.        #2*             ( # --> #*2 )
  2399.        #2+             ( # --> #+2 )
  2400.        #2-             ( # --> #-2 )
  2401.        #2/             ( # --> FLOOR(#/2) )
  2402.        #3+             ( # --> #+3 )
  2403.        #3-             ( # --> #-3 )
  2404.        #4+             ( # --> #+4 )
  2405.        #4-             ( # --> #-4 )
  2406.        #5+             ( # --> #+5 )
  2407.        #5-             ( # --> #-5 )
  2408.        #6*             ( # --> #*6 )
  2409.        #6+             ( # --> #+6 )
  2410.        #7+             ( # --> #+7 )
  2411.        #8*             ( # --> #*8 )
  2412.        #8+             ( # --> #+8 )
  2413.        #9+             ( # --> #+9 )
  2414.        #MAX            ( #2 #1 --> MAX(#2,#1) )
  2415.        #MIN            ( #2 #1 --> MIN(#2,#1) )
  2416.        2DUP#+          ( #2 #1 --> #2 #1 #1+#2 )
  2417.        DROP#1-         ( # ob --> #-1 )
  2418.        DUP#1+          ( # --> # #+1 )
  2419.        DUP#1-          ( # --> # #-1 )
  2420.        DUP3PICK#+      ( #2 #1 --> #2 #1 #1+#2 )
  2421.        OVER#+          ( #2 #1 --> #2 #1+#2 )
  2422.        OVER#-          ( #2 #1 --> #2 #1-#2 )
  2423.        ROT#+           ( #2 ob #1 --> ob #1+#2 )
  2424.        ROT#+SWAP       ( #2 ob #1 --> #1+#2 ob )
  2425.        ROT#-           ( #2 ob #1 --> ob #1-#2 )
  2426.        ROT#1+          ( # ob ob' --> ob ob' #+1 )
  2427.        ROT+SWAP        ( #2 ob #1 --> #1+#2 ob )
  2428.        SWAP#-          ( #2 #1 --> #1-#2 )
  2429.        SWAP#1+         ( # ob --> ob #+1 )
  2430.        SWAP#1+SWAP     ( # ob --> #+1 ob )
  2431.        SWAP#1-         ( # ob --> ob #-1 )
  2432.        SWAP#1-SWAP     ( # ob --> #-1 ob )
  2433.        SWAPOVER#-      ( #2 #1 --> #1 #2-#1 )
  2434.  
  2435.  
  2436.  
  2437.  
  2438.  
  2439.  
  2440.  
  2441.                                  Page 34
  2442.  
  2443.  
  2444.  
  2445.  
  2446.  
  2447.  
  2448.        4.2.2  Conversion_Functions
  2449.  
  2450.        COERCE          ( % --> # )  If %<0 then # is 0
  2451.                                     If %>FFFFF then #=FFFFF
  2452.        COERCE2         ( %2 %1 --> #2 #1 ) See COERCE
  2453.        COERCEDUP       ( % --> # # ) See COERCE COERCESWAP      (
  2454.        ob % --> # ob ) UNCOERCE        ( # --> % )
  2455.        UNCOERCE%%      ( # --> %% ) UNCOERCE2       ( #2 #1 --> %2
  2456.        %1 )
  2457.  
  2458.  
  2459.  
  2460.  
  2461.  
  2462.  
  2463.  
  2464.  
  2465.  
  2466.  
  2467.  
  2468.  
  2469.  
  2470.  
  2471.  
  2472.  
  2473.  
  2474.  
  2475.  
  2476.  
  2477.  
  2478.  
  2479.  
  2480.  
  2481.  
  2482.  
  2483.  
  2484.  
  2485.  
  2486.  
  2487.  
  2488.  
  2489.  
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502.  
  2503.  
  2504.  
  2505.  
  2506.  
  2507.                                  Page 35
  2508.  
  2509.  
  2510.  
  2511.  
  2512.  
  2513.  
  2514.        5.  Character Constants
  2515.  
  2516.        The following words are useful for converting between
  2517.        character objects and other object types:
  2518.  
  2519.        CHR>#           ( chr --> # )
  2520.        #>CHR           ( # --> chr )
  2521.        CHR>$           ( chr --> $ )
  2522.  
  2523.        The following character constants and strings are supported:
  2524.  
  2525.        CHR_# CHR_* CHR_+ CHR_, CHR_- CHR_. CHR_/ CHR_0 CHR_1 CHR_2
  2526.        CHR_3 CHR_4 CHR_5 CHR_6 CHR_7 CHR_8 CHR_9 CHR_: CHR_; CHR_<
  2527.        CHR_= CHR_> CHR_A CHR_B CHR_C CHR_D CHR_E CHR_F CHR_G CHR_H
  2528.        CHR_I CHR_J CHR_K CHR_L CHR_M CHR_N CHR_O CHR_P CHR_Q CHR_R
  2529.        CHR_S CHR_T CHR_U CHR_V CHR_W CHR_X CHR_Y CHR_Z CHR_a CHR_b
  2530.        CHR_c CHR_d CHR_e CHR_f CHR_g CHR_h CHR_i CHR_j CHR_k CHR_l
  2531.        CHR_m CHR_n CHR_o CHR_p CHR_q CHR_r CHR_s CHR_t CHR_u CHR_v
  2532.        CHR_w CHR_x CHR_y CHR_z
  2533.  
  2534.        CHR_00 (hex 0) CHR_...  CHR_DblQuote    CHR_-> CHR_<<
  2535.        CHR_>> CHR_Angle CHR_Deriv CHR_Integral CHR_LeftPar
  2536.        CHR_Newline  CHR_Pi CHR_RightPar CHR_Sigma CHR_Space
  2537.        CHR_UndScore CHR_[  CHR_]  CHR_{ CHR_}  CHR_<= CHR_>=
  2538.        CHR_<>
  2539.  
  2540.        $_R<<           ( $ "R\80\80" "R<angle><angle>" )
  2541.        $_R<Z           ( $ "R\80Z"   "R<angle>Z"       )
  2542.        $_XYZ           ( $ "XYZ"                       )
  2543.        $_<<>>          ( $ "ABBB"                      )
  2544.        $_{}            ( $ "{}"                        )
  2545.        $_[]            ( $ "[]"                        )
  2546.        $_''            ( $ "''"                        )
  2547.        $_::            ( $ "::"                        )
  2548.        $_LRParens      ( $ "()"                        )
  2549.        $_2DQ           ( $ """"""                      )
  2550.        $_ECHO          ( $ "ECHO"                      )
  2551.        $_EXIT          ( $ "EXIT"                      )
  2552.        $_Undefined     ( $ "Undefined"                 )
  2553.        $_RAD           ( $ "RAD"                       )
  2554.        $_GRAD          ( $ "GRAD"                      )
  2555.        NEWLINE$        ( $ "\0a"                       )
  2556.        SPACE$          ( $ " "                         )
  2557.  
  2558.  
  2559.  
  2560.  
  2561.  
  2562.  
  2563.  
  2564.  
  2565.  
  2566.  
  2567.  
  2568.  
  2569.  
  2570.  
  2571.  
  2572.  
  2573.                                  Page 36
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.        6.  Hex & Character Strings
  2581.  
  2582.        6.1  Character Strings
  2583.  
  2584.        The following words are avaliable for character string
  2585.        manipulation:
  2586.  
  2587.        &$              ( $1 $2 --> $3 )
  2588.                          Appends $2 to $1
  2589.        !append$        ( $1 $2 --> $3 )
  2590.                          Same as &$, except that it will attempt the concatenation
  2591.                          "in place," if there is not enough memory for the new
  2592.                          string, and the target is in tempob.
  2593.        $>ID            ( $name --> Id )
  2594.                          Converts string object to name object
  2595.        &$SWAP          ( ob $1 $2 --> $3 ob )
  2596.                          Appends $2 to $1, then swaps result with ob )
  2597.        1-#1-SUB$       ( $ # --> $' )
  2598.                          Where $' = chars 1 thru #-1 of $
  2599.        >H$             ( $ chr --> $' )
  2600.                          Prepends chr to $
  2601.        >T$             ( $ chr --> $' )
  2602.                          Appends chr to $
  2603.        AND$            ( $1 $2 --> $1 AND $2 )
  2604.                          Bitwise logical AND of two strings
  2605.        APPEND_SPACE    ( $ --> $' )
  2606.                          Appends space to $
  2607.        Blank$          ( # --> $  )
  2608.                          Creates a string of # spaces
  2609.        CAR$            ( $ --> chr | $ )
  2610.                          Returns 1st chr of $ or NULL$ if $ is null
  2611.        CDR$            ( $ --> $' )
  2612.                          $' is $ minus first character.  Returns NULL$ if $ is null
  2613.        COERCE$22       ( $ --> $' )
  2614.                          If $ longer than 22 chars., truncates to 21 chars &
  2615.                          appends "..."
  2616.        DECOMP$         ( ob --> $ )
  2617.                          Decompiles object for stack display
  2618.        DO>STR          ( ob --> $ )
  2619.                          Internal version of ->STR
  2620.        DROPNULL$       ( ob --> NULL$ )
  2621.                          Drops object, returns zero-length string
  2622.        DUP$>ID         ( $name --> $name Id )
  2623.                          Dups, converts string object to name object
  2624.        DUPLEN$         ( $ --> $ #length )
  2625.                          Returns $ and its length
  2626.        DUPNULL$?       ( $ --> $ flag )
  2627.                          Returns TRUE if $ is zero-length
  2628.        EDITDECOMP$     ( ob --> $ )
  2629.                          Decompile object for editing
  2630.        JstGETTHEMESG   ( # --> $ )
  2631.                          Fetches message from message table
  2632.        ID>$            ( ID --> $name )
  2633.                          Converts name object to a string
  2634.        LAST$           ( $ # --> $' )
  2635.                          Returns last # chrs of $
  2636.  
  2637.  
  2638.  
  2639.                                  Page 37
  2640.  
  2641.  
  2642.  
  2643.  
  2644.  
  2645.  
  2646.        LEN$            ( $ --> #length )
  2647.                          Returns length of $
  2648.        NEWLINE$&$      ( $ --> $' )
  2649.                          Appends "\0a" to $
  2650.        NULL$           ( --> $ )
  2651.                          Returns empty string
  2652.        NULL$?          ( $ --> flag )
  2653.                          Returns TRUE if $ is zero-length
  2654.        NULL$SWAP       ( ob --> $ ob )
  2655.                          Swaps empty string into level 2
  2656.        NULL$TEMP       ( --> $ )
  2657.                          Creates empty string in TEMPOB
  2658.        OR$             ( $1 $2 --> $3 )
  2659.                          Bitwise logical OR of two strings
  2660.        OVERLEN$        ( $ ob --> $ ob #length )
  2661.                          Returns length of $ in level 2
  2662.        POS$            ( $search $find #start --> #pos )
  2663.                          Returns #pos (#0 if not found) of $find
  2664.                          within $search starting at head of $search
  2665.        POS$REV         ( $search $find #start --> #pos )
  2666.                          Returns #pos (#0 if not found) of $find
  2667.                          within $search starting at tail of $search
  2668.        PromptIdUtil    ( id ob -> $ )
  2669.                          Returns string in the form "id: ob"
  2670.        SEP$NL          ( $ --> $2 $1 )
  2671.                          Separate $ at newline character
  2672.        SUB$            ( $ #start #end --> $' )
  2673.                          Returns substring of $
  2674.        SUB$1#          ( $ #pos --> # )
  2675.                          Returns bint with value of character
  2676.                          in $ at position #pos
  2677.        SUB$SWAP        ( ob $ #start #end --> $' ob )
  2678.                          Returns substring of $ and swaps with ob
  2679.        SWAP&$          ( $1 $2 --> "$2$1" )
  2680.                          Appends $1 to $2
  2681.        TIMESTR         ( %date %time --> "WED 03/30/90 11:30:15A" )
  2682.                          Returns string time and date
  2683.                          (like user word TSTR)
  2684.        XOR$            ( $1 $2 --> $3 )
  2685.                          Bitwise logical XOR of two strings
  2686.        a%>$            ( % --> $ )
  2687.                          Converts % to $ using current display mode
  2688.        a%>$,           ( % --> $ )
  2689.                          Converts % to $ using current display mode
  2690.                          Same as a%>$, but with no commas
  2691.        palparse        ( $ --> ob TRUE         )
  2692.                        ( $ --> $ #pos $' FALSE )
  2693.                          Parse a string into an object and TRUE, or
  2694.                          returns position of error and FALSE
  2695.  
  2696.  
  2697.  
  2698.  
  2699.  
  2700.  
  2701.  
  2702.  
  2703.  
  2704.  
  2705.                                  Page 38
  2706.  
  2707.  
  2708.  
  2709.  
  2710.        6.2  Hex Strings
  2711.  
  2712.  
  2713.        #>%             ( hxs --> % )
  2714.                          Converts hxs to real
  2715.        %>#             ( % --> hxs )
  2716.                          Converts real to hxs
  2717.        &HXS            ( hxs1 hxs2 --> hxs3 )
  2718.                          Appends hxs2 to hxs1
  2719.        2HXSLIST?       ( { hxs1 hxs2 } --> #1 #2 )
  2720.                          Converts list of two hxs into two bints
  2721.                          Generates Bad Argument Value error for
  2722.                          invalid input
  2723.        HXS#HXS         ( hxs1 hxs2 --> %flag )
  2724.                          Returns %1 if hxs1 <> hxs2, otherwise %0
  2725.        HXS>#           ( hxs --> # )
  2726.                          Converts lower 20 bits of hxs into a bint
  2727.        HXS>$           ( hxs --> $ )
  2728.                          Does hxs>$, then appends base character
  2729.        HXS>%           ( hxs --> % )
  2730.                          Converts hex string to real number
  2731.        HXS<HXS         ( hxs1 hxs2 --> %flag )
  2732.                          Returns %1 if hxs1<hxs2, otherwise %0
  2733.        HXS>HXS         ( hxs1 hxs2 --> %flag )
  2734.                          Returns %1 if hxs1>hxs2, otherwise %0
  2735.        HXS>=HXS        ( hxs1 hxs2 --> %flag )
  2736.                          Returns %1 if hxs1>=hxs2, otherwise %0
  2737.        HXS<=HXS        ( hxs1 hxs2 --> %flag )
  2738.                          Returns %1 if hxs1<=hxs2, otherwise %0
  2739.        LENHXS          ( hxs --> #length )
  2740.                          Returns # of nibbles in hxs
  2741.        NULLHXS         ( --> hxs )
  2742.                          Returns zero-length hex string
  2743.        SUBHXS          ( hxs #m #n --> hxs' )
  2744.                          Returns substring
  2745.  
  2746.        User RPL binary integers are actually hex strings.  The
  2747.        following words assume 64-bit or shorter hex strings, and
  2748.        return results according to the current wordsize:
  2749.  
  2750.        bit/            ( hxs1 hxs2 --> hxs3 )
  2751.        Divides hxs1 by hxs2 bit%#/          ( % hxs --> hxs' )
  2752.                          Divides % by hxs, returns hxs
  2753.        bit#%/          ( hxs % --> hxs' )                   Divides
  2754.        hxs by %, returns hxs bit*            ( hxs1 hxs2 --> hxs3 )
  2755.                          Multiplies hxs1 by hxs2 bit%#*          (
  2756.        % hxs --> hxs' )                   Multiplies % by hxs,
  2757.        returns hxs bit#%*          ( hxs % --> hxs' )
  2758.                          Multiplies hxs by %, returns hxs
  2759.        bit+            ( hxs1 hxs2 --> hxs3 )
  2760.        Adds hxs1 to hxs2 bit%#+          ( % hxs --> hxs' )
  2761.                          Adds % to hxs, returns hxs
  2762.        bit#%+          ( hxs % --> hxs' )                   Adds
  2763.        hxs to %, returns hxs bit-            ( hxs1 hxs2 --> hxs3 )
  2764.                          Subtracts hxs2 from hxs1 bit%#-          (
  2765.        % hxs --> hxs' )                   Suptracts % from hxs,
  2766.        returns hxs bit#%-          ( hxs % --> hxs' )
  2767.                          Suptracts hxs from %, returns hxs
  2768.  
  2769.  
  2770.  
  2771.                                  Page 39
  2772.  
  2773.  
  2774.  
  2775.  
  2776.  
  2777.  
  2778.        bitAND          ( hxs1 hxs2 --> hxs3 )
  2779.        Bitwise logical AND bitASR          ( hxs --> hxs' )
  2780.                          Arithmetic shift right one bit
  2781.        bitOR           ( hxs1 hxs2 --> hxs3 )
  2782.        Bitwise logical OR bitNOT          ( hxs1 hxs2 --> hxs3 )
  2783.                          Bitwise logical NOT bitRL           ( hxs
  2784.        --> hxs' )                   Circular left shift by 1 bit
  2785.        bitRLB          ( hxs --> hxs' )                   Circular
  2786.        left shift by 1 byte bitRR           ( hxs --> hxs' )
  2787.                          Circular right shift by 1 bit
  2788.        bitRRB          ( hxs --> hxs' )                   Circular
  2789.        right shift by 1 byte bitSL           ( hxs --> hxs' )
  2790.                          Shift left by 1 bit bitSLB          ( hxs
  2791.        --> hxs' )                   Shift left by 1 byte
  2792.        bitSR           ( hxs --> hxs' )                   Shift
  2793.        right by 1 bit bitSRB          ( hxs --> hxs' )
  2794.                          Shift right by 1 byte bitXOR          (
  2795.        hxs1 hxs2 --> hxs3 )                   Bitwise logical XOR
  2796.  
  2797.  
  2798.        Wordsize control:
  2799.  
  2800.        WORDSIZE        ( --> # )                   Returns user
  2801.        binary integer wordsize dostws          ( # --> )
  2802.                          Stores binary wordsize hxs>$           (
  2803.        hxs --> $ )                   Converts hex string to chr
  2804.        string using the                   current display mode and
  2805.        wordsize
  2806.  
  2807.  
  2808.  
  2809.  
  2810.  
  2811.  
  2812.  
  2813.  
  2814.  
  2815.  
  2816.  
  2817.  
  2818.  
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.  
  2832.  
  2833.  
  2834.  
  2835.  
  2836.  
  2837.                                  Page 40
  2838.  
  2839.  
  2840.  
  2841.  
  2842.        7.  Real Numbers
  2843.  
  2844.        Real numbers are written with %, and extended real numbers
  2845.        are written with %%.
  2846.  
  2847.  
  2848.        7.1  Built-in Reals
  2849.  
  2850.        The following real and extended real numbers are built in:
  2851.  
  2852.        %%.1    %%4    %-8         %11    %21    %5
  2853.        %%.4    %%5    %-9         %12    %22    %6
  2854.        %%.5    %%60   %-MAXREAL   %13    %23    %7
  2855.        %%0     %%7    %-MINREAL   %14    %24    %8
  2856.        %%1     %-2    %.1         %15    %25    %MAXREAL
  2857.        %%10    %-3    %.5         %16    %26    %MINREAL
  2858.        %%12    %-4    %0          %17    %27    %PI
  2859.        %%2     %-5    %1          %180   %3     %e
  2860.        %%2PI   %-6    %10         %2     %360   %-1
  2861.        %%3     %-7    %100        %20    %4
  2862.  
  2863.  
  2864.        7.2  Real Number Functions
  2865.  
  2866.        In the stack diagrams below, %1 and %2 refer to two
  2867.        different real numbers, NOT the real numbers one and two.
  2868.  
  2869.  
  2870.        %%*             ( %%1 %%2 -->  %%3 )
  2871.                          Multiplies two extended reals
  2872.        %%*ROT          ( ob1 ob2 %%1 %%2 --> ob2 %%3 ob1 )
  2873.                          Multiplies two extended reals,
  2874.                          then does a ROT
  2875.        %%*SWAP         ( ob %%1 %%2 --> %%3 ob )
  2876.                          Multiplies two extended reals,
  2877.                          then does a SWAP
  2878.        %%*UNROT        ( ob1 ob2 %%1 %%2 --> %%3 ob1 ob2 )
  2879.                          Multiplies two extended reals,
  2880.                          then does an UNROT
  2881.        %%+             ( %%1 %%2 --> %%3 )
  2882.                          Adds two extended reals
  2883.        %%-             ( %%1 %%2 --> %%3 )
  2884.                          Subtraction
  2885.        %%ABS           ( %% --> %%' )
  2886.                          Absolute value
  2887.        %%ACOSRAD       ( %% --> %%' )
  2888.                          Arc-cosine using radians
  2889.        %%ANGLE         ( %%x %%y --> %%angle )
  2890.                          Angle using current angle mode from %%x %%y
  2891.        %%ANGLEDEG      ( %%x %%y --> %%angle )
  2892.                          Angle using degrees from %%x %%y
  2893.  
  2894.  
  2895.  
  2896.  
  2897.  
  2898.  
  2899.  
  2900.  
  2901.  
  2902.  
  2903.                                  Page 41
  2904.  
  2905.  
  2906.  
  2907.  
  2908.  
  2909.  
  2910.        %%ANGLERAD      ( %%x %%y --> %%angle )
  2911.                          Angle using radians from %%x %%y
  2912.        %%ASINRAD       ( %% --> %%' )
  2913.                          Arc-sine using radians
  2914.        %%CHS           ( %% --> %%' )
  2915.                          Change sign
  2916.        %%COS           ( %% --> %%' )
  2917.                          Cosine
  2918.        %%COSDEG        ( %% --> %%' )
  2919.                          Cosine using degrees
  2920.        %%COSH          ( %% --> %%' )
  2921.                          Hyperbolic cosine
  2922.        %%COSRAD        ( %% --> %%' )
  2923.                          Cosine using radians
  2924.        %%EXP           ( %% --> %%' )
  2925.                          e^x
  2926.        %%FLOOR         ( %% --> %%' )
  2927.                          Greatest integer <= x
  2928.        %%H>HMS         ( %% --> %%' )
  2929.                          Decimal hours to hh.mmss
  2930.        %%INT           ( %% --> %%' )
  2931.                          Integer part
  2932.        %%LN            ( %% --> %%' )
  2933.                          ln(x)
  2934.        %%LNP1          ( %% --> %%' )
  2935.                          ln(x+1)
  2936.        %%MAX           ( %%1 %%2 --> %%3 )
  2937.                          Returns greater of two %%s
  2938.        %%P>R           ( %%radius %%angle --> %%x %%y )
  2939.                          Polar to rectangular conversion
  2940.        %%R>P           ( %%x %%y --> %%radius %%angle )
  2941.                          Rectangular to polar conversion
  2942.        %%SIN           ( %% --> %%' )
  2943.                          Sine
  2944.        %%SINDEG        ( %% --> %%' )
  2945.                          Sine using degrees
  2946.        %%SINH          ( %% --> %%' )
  2947.                          Hyperbolic sine
  2948.        %%SQRT          ( %% --> %%' )
  2949.                          Square root
  2950.        %%TANRAD        ( %% --> %%' )
  2951.                          Tangent using radians
  2952.        %%^             ( %%1 %%2 --> %%3 )
  2953.                          Exponential
  2954.        %+              ( %1 %2 --> %3 )
  2955.                          Addition
  2956.        %+SWAP          ( ob %1 %2 --> %3 ob )
  2957.                          Addition, then SWAP
  2958.        %-              ( %1 %2 --> %3 )
  2959.                          Subtraction
  2960.        %1+             ( % --> %+1 )
  2961.                          Adds one
  2962.        %1-             ( % --> %-1 )
  2963.                          Subtracts one
  2964.  
  2965.  
  2966.  
  2967.  
  2968.  
  2969.                                  Page 42
  2970.  
  2971.  
  2972.  
  2973.  
  2974.        %>#             ( % --> hxs )
  2975.                          Converts real to binary integer
  2976.        %>%%            ( % --> %% )
  2977.                          Converts real to extended real
  2978.        %>%%-           ( %1 %2 --> %%3 )
  2979.                          Converts 2 % to %%, then subtracts
  2980.        %>%%1           ( %x --> %% )
  2981.                          Converts % to %%, then does 1/x
  2982.        %>%%ANGLE       ( %x %y --> %%angle )
  2983.                          Angle in current angle mode
  2984.        %>%%SQRT        ( % --> %% )
  2985.                          Converts % to %%, then sqrt(x)
  2986.        %>%%SWAP        ( ob % --> %% ob )
  2987.                          Converts % to %%, then SWAP
  2988.        %>C%            ( %real %imag --> C% )
  2989.                          Real to complex conversion
  2990.        %>HMS           ( % --> %hh.mmss )
  2991.                          Decimal hours to hh.mmss
  2992.        %ABS            ( % --> %' )
  2993.                          Absolute value
  2994.        %ABSCOERCE      ( % --> # )
  2995.                          Absolute value, convert to bint
  2996.        %ACOS           ( % --> %' )
  2997.                          Arc cosine
  2998.        %ACOSH          ( % --> %' )
  2999.                          Hyperbolic arc cosine
  3000.        %ALOG           ( % --> %' )
  3001.                          10^x
  3002.        %ANGLE          ( %x %y --> %angle )
  3003.                          Angle using current angle mode from %x %y
  3004.        %ASIN           ( % --> %' )
  3005.                          Arc sine
  3006.        %ASINH          ( % --> %' )
  3007.                          Hyperbolic arc sine
  3008.        %ATAN           ( % --> %' )
  3009.                          Arc tangent
  3010.        %ATANH          ( % --> %' )
  3011.                          Hyperbolic arc tangent
  3012.        %CEIL           ( % --> %' )
  3013.                          Next greatest integer
  3014.        %CH             ( %1 %2 --> %3 )
  3015.                          Percent change
  3016.        %CHS            ( % --> %' )
  3017.                          Change sign
  3018.        %COMB           ( %m %n -> %COMB(m,n) )
  3019.                          Combinations of m items taken n at a time
  3020.        %COS            ( % --> %' )
  3021.                          Cosine
  3022.        %COSH           ( % --> %' )
  3023.                          Hyperbolic cosine
  3024.        %D>R            ( % --> %' )
  3025.                          Degrees to radians
  3026.        %EXP            ( % --> %' )
  3027.                          e^x
  3028.        %EXPM1          ( $ --> %' )
  3029.                          e^x-1
  3030.  
  3031.  
  3032.  
  3033.  
  3034.  
  3035.                                  Page 43
  3036.  
  3037.  
  3038.  
  3039.  
  3040.        %EXPONENT       ( % --> %' )
  3041.                          Returns exponent
  3042.        %FACT           ( % --> %! )
  3043.                          Factorial
  3044.        %FLOOR          ( % --> %' )
  3045.                          Greatest integer <= x
  3046.        %FP             ( % --> %' )
  3047.                          Fractional part
  3048.        %HMS+           ( %1 %2 --> %3 )
  3049.                          HH.MMSS addition
  3050.        %HMS-           ( %1 %2 --> %3 )
  3051.                          HH.MMSS subtraction
  3052.        %HMS>           ( % --> %' )
  3053.                          Convert hh.mmss to decimal hours
  3054.        %IP             ( % --> %' )
  3055.                          Integer part
  3056.        %IP>#           ( % --> # )
  3057.                          IP(ABS(x) converted to binary integer
  3058.        %LN             ( % --> %' )
  3059.                          ln(x)
  3060.        %LNP1           ( % --> %' )
  3061.                          ln(x+1)
  3062.        %LOG            ( % --> %' )
  3063.                          Common log
  3064.        %MANTISSA       ( % --> %' )
  3065.                          Returns mantissa
  3066.        %MAX            ( %1 %2 --> % )
  3067.                          Returns larger of two reals
  3068.        %MAXorder       ( %1 %2 --> %larger %smaller )
  3069.                          Orders two numbers
  3070.        %MIN            ( %1 %2 --> % )
  3071.                          Returns smaller of two reals
  3072.        %MOD            ( %1 %2 --> %3 )
  3073.                          Returns %1 MOD %2
  3074.        %NFACT          ( % --> %' )
  3075.                          Factorial
  3076.        %NROOT          ( %1 %2 --> %3 )
  3077.                          Nth root
  3078.        %OF             ( %1 %2 --> %3 )
  3079.                          Returns percantage of %1 that is %2
  3080.        %PERM           ( %m %n --> %PERM(%m,%n) )
  3081.                          Returns permutations of %m items
  3082.                          taken %n at a time
  3083.        %POL>%REC       ( %x %y --> %radius %angle )
  3084.                          Rectangular to polar conversion
  3085.        %R>D            ( %radians --> %degrees )
  3086.                          Radians to degrees
  3087.        %RAN            ( --> %random )
  3088.                          Random number
  3089.        %RANDOMIZE      ( %seed --> )
  3090.                          Updates random number seed, uses the
  3091.                          system clock if %=0
  3092.        %REC>%POL       ( %radius %angle --> %x %y )
  3093.                          Polar to rectangular conversion
  3094.        %SGN            ( % --> %' )
  3095.                          Sign: -1, 0 or 1 returned depending
  3096.                          on the sign of the argument
  3097.        %SIN            ( % --> %' )
  3098.  
  3099.  
  3100.  
  3101.                                  Page 44
  3102.  
  3103.  
  3104.  
  3105.  
  3106.                          Sine
  3107.        %SINH           ( % --> %' )
  3108.                          Hyperbolic sine
  3109.        %SPH>%REC       ( %r %th %ph --> %x %y %z )
  3110.                          Spherical to rectangular conversion
  3111.        %SQRT           ( % --> %' )
  3112.                          Square root
  3113.        %T              ( %1 %2 --> %3 )
  3114.                          Percent total
  3115.        %TAN            ( % --> %' )
  3116.                          Tangent
  3117.        %TANH           ( % --> %' )
  3118.                          Hyperbolic tangent
  3119.        %^              ( %1 %2 --> %3 )
  3120.                          Exponential
  3121.        2%%>%           ( %%1 %%2 --> %1 %2 )
  3122.                          Extended real to real conversion
  3123.        2%>%%           ( %1 %2 --> %%1 %%2 )
  3124.                          Real to extended real conversion
  3125.        C%>%            ( C% --> %real %imag )
  3126.                          Complex to real conversion
  3127.        DDAYS           ( %date1 %date2 --> %diff )
  3128.                          Days between dates in DMY format
  3129.        DORANDOMIZE     ( % --> )
  3130.                          Updates random number seed
  3131.        RNDXY           ( %number %places --> %number' )
  3132.                          Rounds %number to %places
  3133.        TRCXY           ( %number %places --> %number' )
  3134.                          Truncates %number to %places
  3135.        SWAP%>C%        ( %imag %real --> C% )
  3136.                          Real to complex conversion
  3137.  
  3138.  
  3139.  
  3140.  
  3141.  
  3142.  
  3143.  
  3144.  
  3145.  
  3146.  
  3147.  
  3148.  
  3149.  
  3150.  
  3151.  
  3152.  
  3153.  
  3154.  
  3155.  
  3156.  
  3157.  
  3158.  
  3159.  
  3160.  
  3161.  
  3162.  
  3163.  
  3164.  
  3165.  
  3166.  
  3167.                                  Page 45
  3168.  
  3169.  
  3170.  
  3171.  
  3172.        8.  Complex Numbers
  3173.  
  3174.        Complex numbers are represented by C%, extended complex
  3175.        numbers by C%%.
  3176.  
  3177.  
  3178.        8.1  Built-in Complex Numbers
  3179.  
  3180.  
  3181.        C%0             (0,0)
  3182.        C%1             (1,0)
  3183.        C%-1            (-1,0)
  3184.        C%%1            (%%1,%%0)
  3185.  
  3186.  
  3187.        8.2  Conversion Words
  3188.  
  3189.  
  3190.        %>C%            ( %real %imag --> C% )
  3191.        %%>C%%          ( %%real %%imag --> C%% )
  3192.        %%>C%           ( %%real %%imag --> C% )
  3193.        C%>%            ( C% --> %real %imag )
  3194.        C%%>%%          ( C%% --> %%real %%imag )
  3195.        C%%>C%          ( C%% --> C% )
  3196.        C%>%%           ( C% --> %%real %%imag )
  3197.        C%>%%SWAP       ( C% --> %%imag %%real )
  3198.        C>Im%           ( C% --> %imag )
  3199.        C>Re%           ( C% --> %real )
  3200.  
  3201.  
  3202.  
  3203.        8.3  Complex Functions
  3204.  
  3205.  
  3206.        C%1/            ( C% --> C%' )
  3207.                          Inverse
  3208.        C%ABS           ( C% --> % )
  3209.                          Returns SQRT(x^2+y^2) from (x,y)
  3210.        C%ACOS          ( C% --> C%' )
  3211.                          Arc cosine
  3212.        C%ALOG          ( C% --> C%' )
  3213.                          Common antilog
  3214.        C%ARG           ( C% --> %)
  3215.                          Returns ANGLE(x,y) from (x,y)
  3216.        C%ASIN          ( C% --> C%' )
  3217.                          Arc sine
  3218.        C%ATAN          ( C% --> C%' )
  3219.                          Arc tangent
  3220.        C%C^C           ( C%1 C%2 --> C%3 )
  3221.                          Power
  3222.        C%CHS           ( C% --> C%' )
  3223.                          Change sign
  3224.        C%%CHS          ( C%% --> C%%' )
  3225.                          Change sign
  3226.        C%CONJ          ( C% --> C%' )
  3227.                          Conjugate
  3228.        C%%CONJ         ( C%% --> C%%' )
  3229.                          Conjugate
  3230.  
  3231.  
  3232.  
  3233.                                  Page 46
  3234.  
  3235.  
  3236.  
  3237.  
  3238.  
  3239.  
  3240.        C%COS           ( C% --> C%' )
  3241.                          Cosine
  3242.        C%COSH          ( C% --> C%' )
  3243.                          Hyperbolic cosine
  3244.        C%EXP           ( C% --> C%' )
  3245.                          e^z
  3246.        C%LN            ( C% --> C%' )
  3247.                          Natural logarithm
  3248.        C%LOG           ( C% --> C%' )
  3249.                          Common logarithm
  3250.        C%SGN           ( C% --> C%' )
  3251.                          Returns (x/SQRT(x^2+y^2),y/SQRT(x^2+y^2)
  3252.        C%SIN           ( C% --> C%' )
  3253.                          Sine
  3254.        C%SINH          ( C% --> C%' )
  3255.                          Hyperbolic sine
  3256.        C%SQRT          ( C% --> C%' )
  3257.                          Square root
  3258.        C%TAN           ( C% --> C%' )
  3259.                          Tangent
  3260.        C%TANH          ( C% --> C%' )
  3261.                          Hyperbolic tangent
  3262.  
  3263.  
  3264.  
  3265.  
  3266.  
  3267.  
  3268.  
  3269.  
  3270.  
  3271.  
  3272.  
  3273.  
  3274.  
  3275.  
  3276.  
  3277.  
  3278.  
  3279.  
  3280.  
  3281.  
  3282.  
  3283.  
  3284.  
  3285.  
  3286.  
  3287.  
  3288.  
  3289.  
  3290.  
  3291.  
  3292.  
  3293.  
  3294.  
  3295.  
  3296.  
  3297.  
  3298.  
  3299.                                  Page 47
  3300.  
  3301.  
  3302.  
  3303.  
  3304.        9.  Arrays
  3305.  
  3306.        The notation [array] represents a real or complex array.
  3307.        [arry%] and [arryC%] represent real and complex arrays,
  3308.        respectively.  {dims} means a list of array dimensions,
  3309.        which may be either { #cols } or { #rows #cols }.
  3310.  
  3311.        Unless otherwise indicated, the following words do NOT check
  3312.        for out-of-range conditions (i.e. elements specified that
  3313.        are not within the range of the current array).
  3314.        ARSIZE          ( [array] --> #elements )
  3315.                        ( [array] --> {dims} )
  3316.        GETATELN        ( # [array] --> ob TRUE )
  3317.                        ( # [array] --> FALSE ) (no such element)
  3318.        MAKEARRY        ( {dims} ob --> [array] )
  3319.                          Creates an unlinked array having the same
  3320.                          element type as ob.  All elements are
  3321.                          initialized to ob.
  3322.        MATCON          ( [arry%] % --> [arry%]' )
  3323.                        ( [arryC%] C% --> [arryC%]' )
  3324.                          Sets all elements in array to % or C%.
  3325.        MATREDIM        ( [array] {dims} --> [array]' )
  3326.        MATTRN          ( [array] --> [array]' )
  3327.        MDIMS           ( [1-D array] --> #m FALSE )
  3328.                        ( [2-D array] --> #m #n TRUE )
  3329.        MDIMSDROP       ( [2-D array] --> #m #n )
  3330.                          Don't use MDIMSDROP on a vector!
  3331.        OVERARSIZE      ( [array] ob --> [array] ob #elements )
  3332.        PULLREALEL      ( [arry%] # --> [arry%] % )
  3333.        PULLCMPEL       ( [arryC%] # --> [arryC%] C% )
  3334.        PUTEL           ( [arry%] % # --> [arry%]' )
  3335.                        ( [arryC%] C% # --> [arryC%] )
  3336.        PUTREALEL       ( [arry%] % # --> [arry%]' )
  3337.        PUTCMPEL        ( [arryC%] C% # --> [arryC%]' )
  3338.  
  3339.  
  3340.  
  3341.  
  3342.  
  3343.  
  3344.  
  3345.  
  3346.  
  3347.  
  3348.  
  3349.  
  3350.  
  3351.  
  3352.  
  3353.  
  3354.  
  3355.  
  3356.  
  3357.  
  3358.  
  3359.  
  3360.  
  3361.  
  3362.  
  3363.  
  3364.  
  3365.                                  Page 48
  3366.  
  3367.  
  3368.  
  3369.  
  3370.  
  3371.  
  3372.        10.  Composite Objects
  3373.  
  3374.        The words described in this chapter are used for
  3375.        manipulating composite objects - mainly lists and
  3376.        secondaries. In the notation below, the term "comp" refers
  3377.        to either any composite object.  The term "#n" refers to the
  3378.        number of objects in a composite object, and the term "#i"
  3379.        refers to the index of an object within a composite.  The
  3380.        term "flag" refers to TRUE or FALSE.
  3381.  
  3382.        &COMP           ( comp comp' --> comp'' ) comp is concatenated to comp'
  3383.        2Ob>Seco        ( ob1 ob2 --> :: ob1 ob2 ; )
  3384.        ::N             ( obn ... ob1 #n --> :: obn ... ob1 ; )
  3385.        ::NEVAL         ( obn ... ob1 #n --> ? )
  3386.                          Does ::N, then evaluates secondary
  3387.        >TCOMP          ( comp ob --> comp' ) ob is added to the tail of comp
  3388.        CARCOMP         ( comp --> ob )
  3389.                        ( comp --> comp )
  3390.                          Returns first object in the core of the
  3391.                          composite.  Returns an null comp if the
  3392.                          supplied composite is null.
  3393.        CDRCOMP         ( comp --> comp' )
  3394.                        ( comp --> comp )
  3395.                          Returns the core of the composite minus the
  3396.                          first object. Returns null comp if if the
  3397.                          supplied composite is null.
  3398.        DUPINCOMP       ( comp --> comp obn ... ob1 #n )
  3399.        DUPLENCOMP      ( comp --> comp #n )
  3400.        DUPNULLCOMP?    ( comp --> comp flag ) TRUE if comp is null.
  3401.        DUPNULL{}?      ( {list} --> {list} flag ) TRUE if {list} is null.
  3402.        EQUALPOSCOMP    ( comp ob --> #pos | #0 )
  3403.                          Returns the index of the first object in comp
  3404.                          matching (EQUAL) ob (see NTHOF also)
  3405.        Embedded?       ( ob1 ob2 --> flag )
  3406.                          Returns TRUE if ob2 is embedded in, or the
  3407.                          same as, ob1; otherwise returns FALSE.
  3408.        INCOMPDROP      ( comp --> obn ... ob1 )
  3409.        INNERCOMP       ( comp --> obn ... ob1 #n )
  3410.        INNERDUP        ( comp --> obn ... ob1 #n #n )
  3411.        LENCOMP         ( comp --> #n )
  3412.        NEXTCOMPOB      ( comp #offset --> comp #offset' ob TRUE )
  3413.                        ( comp #offset --> comp FALSE )
  3414.                          #offset is the nibble offset from the start
  3415.                          of the list to the Nth object in the list.
  3416.                          Returns a new #offset and the next object if
  3417.                          the next object is not SEMI, otherwise
  3418.                          returns the list and FALSE.  Use #5 at the
  3419.                          start of the list.
  3420.        NTHCOMDDUP      ( comp #i --> ob ob )
  3421.        NTHCOMPDROP     ( comp #i --> ob )
  3422.        NTHELCOMP       ( comp #i --> ob TRUE )
  3423.                        ( comp #i --> FALSE )
  3424.                          Returns FALSE if #i is out of range
  3425.        NTHOF           ( ob comp --> #i | #0 ) Same as SWAP EQUALPOSCOMP.
  3426.        NULL::          ( --> :: ; ) (Returns null secondary)
  3427.        NULL{}          ( --> { } )  (Returns null list)
  3428.  
  3429.  
  3430.  
  3431.                                  Page 49
  3432.  
  3433.  
  3434.  
  3435.  
  3436.  
  3437.  
  3438.        ONE{}N          ( ob --> { ob } )
  3439.        Ob>Seco         ( ob --> :: ob ; )
  3440.        POSCOMP         ( comp ob pred --> #i | #0 )
  3441.                          If the specified object "matches" an element
  3442.                          of the specified composite, where "match" is
  3443.                          defined as the specified predicate returning
  3444.                          TRUE when applied to an element of the comp
  3445.                          and the object, then POSCOMP returns the left-
  3446.                          to- right index of the element within the
  3447.                          composite, or zero.  For instance, to find the
  3448.                          first real less than 5 in a list of reals:
  3449.  
  3450.                                    :: {list} 5 ' %< POSCOMP ;
  3451.  
  3452.        PUTLIST         ( ob #i {list} --> {list}' ) (Assumes 0<#i<=#n)
  3453.        SUBCOMP         ( comp #m #n --> comp' ) (Returns subcomposite)
  3454.                          IF #m > #n THEN comp' is null
  3455.                          IF #m=0    THEN #m is set to 1
  3456.                          IF #n=0    THEN #n is set to 1
  3457.                          IF #m > LEN(comp) THEN comp' is null
  3458.                          IF #n > LEN(comp) THEN #n is set to LEN(comp)
  3459.        SWAPINCOMP      ( comp obj --> obj obn ... ob1 #n )
  3460.        THREE{}N        ( ob1 ob2 ob3 --> { ob1 ob2 ob3 } )
  3461.        TWO{}N          ( ob1 ob2 --> { ob1 ob2 } )
  3462.        {}N             ( obn ... ob1 #n --> {list} )
  3463.        apndvarlst      ( {list} ob --> {list}' )
  3464.                          Adds ob to the list if ob is not found within
  3465.                          the list
  3466.        matchob?        ( ob comp --> ob TRUE )
  3467.                        ( ob comp --> FALSE )
  3468.                          Determines if ob is equal (EQUAL) to any element of comp
  3469.  
  3470.  
  3471.  
  3472.  
  3473.  
  3474.  
  3475.  
  3476.  
  3477.  
  3478.  
  3479.  
  3480.  
  3481.  
  3482.  
  3483.  
  3484.  
  3485.  
  3486.  
  3487.  
  3488.  
  3489.  
  3490.  
  3491.  
  3492.  
  3493.  
  3494.  
  3495.  
  3496.  
  3497.                                  Page 50
  3498.  
  3499.  
  3500.  
  3501.  
  3502.        11.  Tagged Objects
  3503.  
  3504.        The following words are available for manipulating tagged
  3505.        objects.  Remember that an object can have multiple tags.
  3506.  
  3507.        %>TAG           ( ob % --> tagged )
  3508.                          Tags ob with %
  3509.  
  3510.        >TAG            ( ob $ --> tagged )
  3511.                          Tags ob with $
  3512.  
  3513.        ID>TAG          ( ob id/lam --> tagged )
  3514.                          Tags ob with id
  3515.  
  3516.        STRIPTAGS       ( tagged --> ob )
  3517.                          Removes all tags
  3518.  
  3519.        STRIPTAGSl2     ( tagged ob' --> ob ob' )
  3520.                          Strips tags from level 2 object
  3521.  
  3522.        TAGOBS          ( ob $ --> tagged )
  3523.                        ( ob1 ... obn { $1 ... $n }
  3524.                          --> tagged1 ... taggedn )
  3525.                          Tags one object, or several objects
  3526.                          if a list of tags is in level 1
  3527.  
  3528.        USER$>TAG       ( ob $ --> tagged )
  3529.                          Tags ob with $ (up to 255 chrs valid)
  3530.  
  3531.  
  3532.  
  3533.  
  3534.  
  3535.  
  3536.  
  3537.  
  3538.  
  3539.  
  3540.  
  3541.  
  3542.  
  3543.  
  3544.  
  3545.  
  3546.  
  3547.  
  3548.  
  3549.  
  3550.  
  3551.  
  3552.  
  3553.  
  3554.  
  3555.  
  3556.  
  3557.  
  3558.  
  3559.  
  3560.  
  3561.  
  3562.  
  3563.                                  Page 51
  3564.  
  3565.  
  3566.  
  3567.  
  3568.  
  3569.  
  3570.        12.  Unit Objects
  3571.  
  3572.        When unit objects are compared for dimensional consistency,
  3573.        a hex string, called a "quantity string", may be extracted
  3574.        using the word U>NCQ.  This quantity string contains
  3575.        information about which units are contained, and can be
  3576.        directly compared with another quantity string.  If the
  3577.        quantity strings match, the two unit objects can be said to
  3578.        be dimensionally consistent.  U>NCQ also returns extended
  3579.        real numbers consisting of the number and a conversion
  3580.        factor to base units.
  3581.  
  3582.        U>NCQ           ( unit --> n%% cf%% qhxs )
  3583.                          Returns number, conversion factor,
  3584.                          and hex quantity string
  3585.        UM=?            ( unit1 unit2 --> %flag )
  3586.                          Returns %1 if two unit obs are equal
  3587.        UM#?            ( unit1 unit2 --> %flag )
  3588.                          Returns %1 if unit1 <> unit2
  3589.        UM<?            ( unit1 unit2 --> %flag )
  3590.                          Returns %1 if unit1 < unit2
  3591.        UM>?            ( unit1 unit2 --> %flag )
  3592.                          Returns %1 if unit1 > unit2
  3593.        UM<=?           ( unit1 unit2 --> %flag )
  3594.                          Returns %1 if unit1 <= unit2
  3595.        UM>=?           ( unit1 unit2 --> %flag )
  3596.                          Returns %1 if unit1 >= unit2
  3597.        UM>U            ( % unit --> unit' )
  3598.                          Replaces the number part of a unit object
  3599.        UM%             ( unit %percentage --> unit' )
  3600.                          Returns a percentage of a unit object
  3601.        UM%CH           ( unit1 unit2 --> % )
  3602.                          Returns percent difference
  3603.        UM%T            ( unit1 unit2 --> % )
  3604.                          Returns percentage fraction
  3605.        UM+             ( unit1 unit2 --> unit3 )
  3606.                          Addition
  3607.        UM-             ( unit1 unit2 --> unit3 )
  3608.                          Subtraction
  3609.        UM*             ( unit1 unit2 --> unit3 )
  3610.                          Multiply
  3611.        UM/             ( unit1 unit2 --> unit3 )
  3612.                          Divide
  3613.        UM^             ( unit1 unit2 --> unit3 )
  3614.                          Power
  3615.        UM1/            ( unit --> unit' )
  3616.                          Inverse
  3617.        UMABS           ( unit --> unit' )
  3618.                          Absolute value
  3619.        UMCHS           ( unit --> unit' )
  3620.                          Change sign
  3621.        UMCONV          ( unit1 unit2 --> unit1' )
  3622.                          Converts unit1 to units of unit2
  3623.        UMCOS           ( unit --> unit' )
  3624.                          Cosine
  3625.        UMMAX           ( unit1 unit2 --> unit? )
  3626.  
  3627.  
  3628.  
  3629.                                  Page 52
  3630.  
  3631.  
  3632.  
  3633.  
  3634.  
  3635.  
  3636.                          Returns larger of unit1 and unit2
  3637.        UMMIN           ( unit1 unit2 --> unit? )
  3638.                          Returns smaller of unit1 and unit2
  3639.        UMSI            ( unit --> unit' )
  3640.                          Convert to SI base units
  3641.        UMSIN           ( unit --> unit' )
  3642.                          Sine
  3643.        UMSQ            ( unit --> unit' )
  3644.                          Square
  3645.        UMSQRT          ( unit --> unit' )
  3646.                          Square root
  3647.        UMTAN           ( unit --> unit' )
  3648.                          Tangent
  3649.        UMU>            ( unit --> % unit' )
  3650.                          Returns number and normalized unit parts
  3651.                          of a unit object
  3652.        UMXROOT         ( unit1 unit2 --> unit3 )
  3653.                          unit1^1/unit2
  3654.        UNIT>$          ( unit --> $ )
  3655.                          Decompiles a unit object with tics
  3656.  
  3657.  
  3658.  
  3659.  
  3660.  
  3661.  
  3662.  
  3663.  
  3664.  
  3665.  
  3666.  
  3667.  
  3668.  
  3669.  
  3670.  
  3671.  
  3672.  
  3673.  
  3674.  
  3675.  
  3676.  
  3677.  
  3678.  
  3679.  
  3680.  
  3681.  
  3682.  
  3683.  
  3684.  
  3685.  
  3686.  
  3687.  
  3688.  
  3689.  
  3690.  
  3691.  
  3692.  
  3693.  
  3694.  
  3695.                                  Page 53
  3696.  
  3697.  
  3698.  
  3699.  
  3700.        13.  Temporary Variables and Temporary Environments
  3701.  
  3702.        One of the features implemented in RPL is the capability of
  3703.        creating temporary variables (aka "local variables", "lambda
  3704.        variables") whose names are given by the programmer, and
  3705.        which can be destroyed easily when they are no longer
  3706.        needed. These temporary variables serve a number of
  3707.        important purposes. First of all, they can be used to
  3708.        eliminate stack manipulations within a program, which makes
  3709.        the task of keeping track of the stack much easier, and
  3710.        makes debugging easier. In addition, they are essential for
  3711.        the implementation of programs which take an indefinite
  3712.        number of parameters and want to save one or more of those
  3713.        parameters.
  3714.  
  3715.        Temporary variables are referenced by temporary identifier
  3716.        objects ("local names"), and the binding between a temporary
  3717.        identifier object and its value is supported by structures
  3718.        in memory called temporary environments. (This is the RPL
  3719.        analogue of LISP "lambda binding").
  3720.  
  3721.        Temporary environments are stacked in chronological order.
  3722.        This allows the programmer the opportunity to create his own
  3723.        "private" temporary variables, without the possibility of
  3724.        interfering with those created by others. When a temporary
  3725.        identifier object is executed, a search is made through the
  3726.        stack of temporary environments, starting in the most
  3727.        recently created and working back through previous
  3728.        environments if necessary. When a match is made between the
  3729.        temporary identifier object being executed and a temporary
  3730.        identifier object in one of the temporary environments, the
  3731.        object bound to that identifier is pushed onto the data
  3732.        stack.  Executing an unbound temporary identifier object is
  3733.        an error condition.
  3734.  
  3735.        The processes of creating a temporary environment and
  3736.        assigning initial values to its temporary variables are
  3737.        accomplished simultaneously with the provided object BIND.
  3738.        BIND expects a list of temporary identifier objects on the
  3739.        top of the data stack and at least as many objects
  3740.        (excluding the list itself) on the stack as there are
  3741.        temporary identifier objects in the list. BIND will then
  3742.        create a temporary environment and bind each temporary
  3743.        identifier object in the list with an object on the stack,
  3744.        removing that object from the stack.
  3745.  
  3746.        Subsequent execution of any of the temporary identifier
  3747.        objects in the list will return the object bound to it.  The
  3748.        value bound to a temporary identifier object can be changed
  3749.        using STO in exactly the same manner as a value "bound" to
  3750.        an identifier object (global name).
  3751.  
  3752.        The dissolution of a temporary environment is accomplished
  3753.        with the provided object ABND (short for "abanbon"). ABND
  3754.        removes the top-most temporary environment from the stack of
  3755.        temporary environments. Individual temporary variables
  3756.        cannot be removed from a temporary environment; the
  3757.        temporary environment as a whole must be abandoned.
  3758.  
  3759.  
  3760.  
  3761.                                  Page 54
  3762.  
  3763.  
  3764.  
  3765.  
  3766.  
  3767.  
  3768.        Note that the RPL compiler does not check to see if there is
  3769.        an ABND to match each BIND.  You can include the two within
  3770.        a single program, or put them in separate programs as you
  3771.        like with no restrictions other than the requirements of
  3772.        good structured programming practice.  This also means that
  3773.        you must remember to include the ABND at some point,
  3774.        otherwise you may leave unnecessary environments around
  3775.        after a program has completed execution.  (In user RPL, you
  3776.        do not have such freedom.  The structure word -> has BIND
  3777.        built into it, and the command line parser demands that
  3778.        there be a matching >> or ' that includes ABND.)
  3779.  
  3780.  
  3781.        13.1  Structure of the Temporary Environment Area
  3782.  
  3783.        The structure of the temporary environment area is shown
  3784.        below.
  3785.  
  3786.                             --------------------------
  3787.                             |      Link Field        |-----+      (The first
  3788.                     ---------------------------------|     |       temporary
  3789.                     |   First Temporary Environment  |     |       environment
  3790.                     ----------------------------------     |       is that most
  3791.                                                            |       recently
  3792.                             --------------------------     |       created)
  3793.                +------------|      Link Field        |<----+
  3794.                |    ---------------------------------|
  3795.                |    |  Second Temporary Environment  |
  3796.                |    ----------------------------------
  3797.                .                       .
  3798.                .                       .
  3799.                .                       .
  3800.                |             -------------------------
  3801.                +-----------> |     Link Field        |-----+
  3802.                     ---------------------------------|     |
  3803.                     |    Last Temporary Environment  |     |
  3804.                     ----------------------------------     |
  3805.                                                            |
  3806.                              -------------------------     |
  3807.                              |          0            |<----+
  3808.                              -------------------------
  3809.                                                                 (high memory)
  3810.  
  3811.  
  3812.  
  3813.  
  3814.  
  3815.  
  3816.  
  3817.  
  3818.  
  3819.  
  3820.  
  3821.  
  3822.  
  3823.  
  3824.  
  3825.  
  3826.  
  3827.                                  Page 55
  3828.  
  3829.  
  3830.  
  3831.  
  3832.  
  3833.  
  3834.        Each temporary environment consists of a protection word (a
  3835.        binary integer object body) which is used in error handling,
  3836.        followed by a sequence of one or more pairs of object
  3837.        pointers. The first object pointer in each pair is the
  3838.        address of a temporary identifier object and the second
  3839.        object pointer in each pair is the address of the object
  3840.        bound to that temporary identifier object. All of the object
  3841.        pointers in a temporary environment are updatable.  The
  3842.        structure of each temporary environment within the temporary
  3843.        environment area is shown below.
  3844.  
  3845.          -----------------------------------------------------  (lower addresses)
  3846.          |                Protection Word                    |
  3847.          |---------------------------------------------------|
  3848.          |        -> Temporary Identifier Object 1           |
  3849.          |---------------------------------------------------|
  3850.          | -> Object Bound to Temporary Identifier Object 1  |
  3851.          |---------------------------------------------------|
  3852.          |         -> Temporary Identifier Object 2          |
  3853.          |---------------------------------------------------|
  3854.          | -> Object Bound to Temporary Identifier Object 2  |
  3855.          |---------------------------------------------------|
  3856.          |                      .                            |
  3857.          |                      .                            |
  3858.          |                      .                            |
  3859.          |---------------------------------------------------|
  3860.          |         -> Temporary Identifier Object N          |
  3861.          |---------------------------------------------------|
  3862.          | -> Object Bound to Temporary Identifier Object N  |
  3863.          -----------------------------------------------------  (higher addresses)
  3864.  
  3865.  
  3866.  
  3867.  
  3868.  
  3869.  
  3870.  
  3871.  
  3872.  
  3873.  
  3874.  
  3875.  
  3876.  
  3877.  
  3878.  
  3879.  
  3880.  
  3881.  
  3882.  
  3883.  
  3884.  
  3885.  
  3886.  
  3887.  
  3888.  
  3889.  
  3890.  
  3891.  
  3892.  
  3893.                                  Page 56
  3894.  
  3895.  
  3896.  
  3897.  
  3898.        13.2  Named vs. Unnamed Temporary Variables
  3899.  
  3900.        Temporary variables are normally named by the corresponding
  3901.        temporary identifier in the list used by BIND.  The names in
  3902.        the list are used in the same order as the bound objects
  3903.        appear on the stack--the last identifier in the list
  3904.        corresponds to the object in level 1, the next-to-last
  3905.        identifier corresponds to the object in level 2, and so on.
  3906.        In the following example, the binary integer ONE is bound
  3907.        into Var1, and TWO is bound into Var2:
  3908.  
  3909.            ONE TWO
  3910.            {
  3911.              ' LAM Var1
  3912.              ' LAM Var2
  3913.            }
  3914.            BIND                ( Binds ONE into temporary variable Var1, and
  3915.                                   TWO into variable Var2 )
  3916.            ...
  3917.            LAM Var1            ( Recalls ONE from Var1 )
  3918.            ...
  3919.            LAM Var2            ( Recalls TWO from Var2 )
  3920.            ...
  3921.            ' LAM Var1 STO      ( Stores new object in Var1 )
  3922.            ...
  3923.            ABND                ( Abandons temp env. )
  3924.  
  3925.  
  3926.        Temporary identifiers may contain any text characters,
  3927.        except that you should not start the names with ' or # as
  3928.        such names are reserved for the built-in ROM programs.  For
  3929.        similar reasons, it is recommended that you use names that
  3930.        can not conflict with user-generated names; an easy way to
  3931.        insure this is to include an "illegal" character such as one
  3932.        of the object delimiters in your names.
  3933.  
  3934.  
  3935.  
  3936.  
  3937.  
  3938.  
  3939.  
  3940.  
  3941.  
  3942.  
  3943.  
  3944.  
  3945.  
  3946.  
  3947.  
  3948.  
  3949.  
  3950.  
  3951.  
  3952.  
  3953.  
  3954.  
  3955.  
  3956.  
  3957.  
  3958.  
  3959.                                  Page 57
  3960.  
  3961.  
  3962.  
  3963.  
  3964.  
  3965.  
  3966.        If there is NO CHANCE that another temporary environment
  3967.        will be created above the environment you are about to
  3968.        create, null names may be used to save memory.  There are a
  3969.        number of utility words that allow you to access local
  3970.        variables in the topmost environment by position number,
  3971.        which is faster than the ordinary name resolution.  For
  3972.        example, the example above would look like this:
  3973.  
  3974.          ::
  3975.            ONE TWO
  3976.            { NULLLAM NULLLAM }
  3977.            BIND                ( Binds ONE and TWO into nullnamed temporary
  3978.                                  variables )
  3979.            ...
  3980.            2GETLAM             ( Recalls ONE from first variable )
  3981.            ...
  3982.            1GETLAM             ( Recalls TWO from last variable )
  3983.            ...
  3984.            2PUTLAM             ( Stores new object in first variable )
  3985.            ...
  3986.            ABND                ( Abandons temp environment. )
  3987.          ;
  3988.  
  3989.        The numbering starts with the last temporary variable (i.e.
  3990.        in the same order as the stack level number).
  3991.  
  3992.  
  3993.  
  3994.  
  3995.  
  3996.  
  3997.  
  3998.  
  3999.  
  4000.  
  4001.  
  4002.  
  4003.  
  4004.  
  4005.  
  4006.  
  4007.  
  4008.  
  4009.  
  4010.  
  4011.  
  4012.  
  4013.  
  4014.  
  4015.  
  4016.  
  4017.  
  4018.  
  4019.  
  4020.  
  4021.  
  4022.  
  4023.  
  4024.  
  4025.                                  Page 58
  4026.  
  4027.  
  4028.  
  4029.  
  4030.        13.3  Provided Words for Temporary Variables
  4031.  
  4032.        The following words are provided for working with temporary
  4033.        variables.  The term "lamob" is used in this case to
  4034.        indicate an object recalled from a termporary variable.
  4035.  
  4036.        1ABNDSWAP       ( ob --> lamob ob )
  4037.                          Does :: 1GETLAM ABND SWAP ;
  4038.        1GETABND        ( --> lamob )
  4039.                          Does :: 1GETLAM ABND ;
  4040.        1GETLAM
  4041.         ...            ( --> ob )
  4042.        22GETLAM         Returns contents of Nth lam
  4043.  
  4044.        1GETSWAP        ( ob --> lamob ob )
  4045.                          Does :: 1GETLAM SWAP ;
  4046.        1LAMBIND        ( ob --> )
  4047.                          Does :: 1NULLLAM{} BIND ;
  4048.        1NULLLAM{}      ( --> { NULLLAM } )
  4049.                          Returns list with one null lam
  4050.        1PUTLAM
  4051.         ...            ( ob --> )
  4052.        22PUTLAM        ( Stores ob into Nth lam
  4053.  
  4054.        2GETEVAL        ( --> ? )
  4055.                          Recalls & evaluates ob in 2nd lam
  4056.        @LAM            ( id --> ob TRUE )
  4057.                        ( id --> FALSE )
  4058.                          Recalls lam by name, returns ob and
  4059.                          TRUE if id exists; FALSE otherwise
  4060.        ABND            ( --> )
  4061.                          Abandons topmost temp var env.
  4062.        BIND            ( ob ... { id ... } --> )
  4063.                          Creates new temp var env.
  4064.        CACHE           ( obn ... ob1 n lam --> ) Saves away n objects plus the count
  4065.                          n in a temporary environment, each object being bound to the
  4066.                          same identifier lam.  The last pair has the count. )
  4067.        DUMP            ( NULLLAM --> ob1..obn n ) DUMP is essentially the inverse of
  4068.                          CACHE, BUT: it ONLY works with NULLLAM as the cached name,
  4069.                          and it ALWAYS does a garbage collect.
  4070.        DUP1LAMBIND     ( ob --> ob )
  4071.                          Does DUP, then 1LAMBIND
  4072.        DUP4PUTLAM      ( ob --> ob )
  4073.                          Does DUP, then 4PUTLAM
  4074.        DUPTEMPENV      ( --> )
  4075.                          Duplicates topmost temporary env.,
  4076.                          clearing the protection word.
  4077.        GETLAM          ( #n --> ob )
  4078.                          Returns object in #nth temp var
  4079.        NULLLAM         ( --> NULLLAM )
  4080.                          Null temporary variable name
  4081.        PUTLAM          ( ob #n --> )
  4082.                          Stores ob in #nth temp var
  4083.        STO             ( ob id --> )
  4084.                          Stores ob in named global/temp var
  4085.        STOLAM          ( ob id --> )
  4086.                          Stores ob in named temp var
  4087.  
  4088.  
  4089.  
  4090.  
  4091.                                  Page 59
  4092.  
  4093.  
  4094.  
  4095.  
  4096.  
  4097.  
  4098.        13.4  Coding Suggestions
  4099.  
  4100.        The DEFINE feature of the RPL compiler can be used to
  4101.        combine the legibility of named variables with the speed and
  4102.        efficiency of null-named variables.  For example:
  4103.  
  4104.          DEFINE RclCode  1GETLAM
  4105.          DEFINE StoCode  1PUTLAM
  4106.          DEFINE RclName  2GETLAM
  4107.          DEFINE StoName  2PUTLAM
  4108.          ::
  4109.            ...
  4110.            { NULLLAM NULLLAM }
  4111.            BIND                ( Binds two objects into nullnamed
  4112.                                   temp variables 1 and 2 )
  4113.            ...
  4114.            RclCode             ( Recalls contents of last variable )
  4115.            ...
  4116.            RclName             ( Recalls contents of first variable )
  4117.            ...
  4118.            StoCode             ( Stores object in first variable )
  4119.            ...
  4120.            ABND                ( Abandons temp environment. )
  4121.          ;
  4122.  
  4123.        If a large number of temporary variables are to be used
  4124.        without names, here is a code-saving tip:
  4125.  
  4126.        Replace:
  4127.  
  4128.                ...
  4129.                {
  4130.                  NULLLAM NULLLAM NULLLAM NULLLAM
  4131.                  NULLLAM NULLLAM NULLLAM NULLLAM
  4132.                  NULLLAM NULLLAM NULLLAM NULLLAM
  4133.                  NULLLAM NULLLAM NULLLAM NULLLAM
  4134.                  NULLLAM NULLLAM NULLLAM NULLLAM
  4135.                  NULLLAM NULLLAM NULLLAM NULLLAM
  4136.                } BIND
  4137.                ...
  4138.  
  4139.        With:
  4140.  
  4141.                NULLLAM TWENTYFOUR NDUPN
  4142.                TWENTYFOUR {}N BIND
  4143.  
  4144.        The first method takes 67.5 bytes, whereas the latter method
  4145.        takes 15 bytes, so there's a savings of 52.5 bytes!
  4146.  
  4147.        You can also use TWENTYFOUR ' NULLLAM CACHE, which is
  4148.        shorter yet and does not require building the list of null
  4149.        identifiers in tempob.  Note, however, that CACHE adds an
  4150.        extra temporary variable (to hold the count), so all of the
  4151.        variable position numbers differ by one from the previous
  4152.        methods.
  4153.  
  4154.  
  4155.  
  4156.  
  4157.                                  Page 60
  4158.  
  4159.  
  4160.  
  4161.  
  4162.  
  4163.  
  4164.        14.  Checking Arguments
  4165.  
  4166.        Any program object which can be executed directly by a user
  4167.        should insure that the correct number and types of arguments
  4168.        are present to prevent problems.  If the object is
  4169.        ultimately to be a library command, then it should follow
  4170.        the command structure convention (see section xxx):
  4171.  
  4172.                :: CK0 ... ; for 0 argument commands, or
  4173.  
  4174.                :: CK<n>&Dispatch type1 action1
  4175.                                  type2 action2
  4176.                                       ...
  4177.                                  typen actionn
  4178.                ;
  4179.  
  4180.                for <n> argument commands, where typei is a type
  4181.        code and
  4182.                actioni is the corresponding dispatchee for that
  4183.        type combination, or
  4184.  
  4185.                :: CKN ... ;  for commands that take an number of
  4186.        arguments specified
  4187.                by a real number in level 1 (like PICK or ->LIST).
  4188.  
  4189.        CK<n>&Dispatch is actually a combination of CK<n> and
  4190.        CK&DISPATCH1.  There are a few built-in commands (e.g. TYPE)
  4191.        that use the two words instead of the combined form, but all
  4192.        algebraic functions must use CK<n>&Dispatch since these
  4193.        words also serve to identify the argument count used by a
  4194.        function.
  4195.  
  4196.        If an object is not intended as a library command, then it
  4197.        should have the following structure:
  4198.  
  4199.                :: CK0NOLASTWD ... ; for 0 argument programs, or
  4200.  
  4201.                :: CK<n>NOLASTWD CK<n>&DISPATCH1 type1 action1
  4202.                                  type2 action2
  4203.                                       ...
  4204.                                  typen actionn
  4205.                ;
  4206.  
  4207.                for <n> argument programs, or
  4208.  
  4209.                :: CKNNOLASTWD ... ; for programs that take
  4210.        arguments as specified
  4211.                in level 1.
  4212.  
  4213.  
  4214.  
  4215.  
  4216.  
  4217.  
  4218.  
  4219.  
  4220.  
  4221.  
  4222.  
  4223.                                  Page 61
  4224.  
  4225.  
  4226.  
  4227.  
  4228.  
  4229.  
  4230.        14.1  Number of Arguments
  4231.  
  4232.        The following words verify that from 0-5 arguments are on
  4233.        the stack, and issue the "Too Few Arguments" error
  4234.        otherwise.
  4235.  
  4236.        CK0, CK0NOLASTWD                No arguments required
  4237.        CK1, CK1NOLASTWD                One argument required
  4238.        CK2, CK2NOLASTWD                Two arguments required
  4239.        CK3, CK3NOLASTWD                Three arguments required
  4240.        CK4, CK4NOLASTWD                Four arguments required
  4241.        CK5, CK5NOLASTWD                Five arguments required
  4242.  
  4243.        Each word CK<n>... "marks" the stack below the <n>th argument, and
  4244.        if argument recovery is in effect, saves a copy of the <n> arguments in the
  4245.        last argument save area.  If an error
  4246.        occurs that is handled by the outer loop error handler, then the stack
  4247.        is cleared to the marked level (this removes any stray objects that
  4248.        were not put there by the user).  If the argument recovery system is active,
  4249.        then the saved arguments are restored to the stack.
  4250.  
  4251.        Any CK<n> also records the command in which it is executed, again for the
  4252.        sake of the outer loop error handler, which uses the command name as
  4253.        part of the error message display.  A CK<n> should only be used in
  4254.        library commands, and must be the first object in the command program.
  4255.        CK<n>NOLASTWD does not record the command, and may be used at any point.
  4256.        However, it generally not a good idea to execute these words except
  4257.  
  4258.        * at the beginning of a user-executed object, or
  4259.  
  4260.        * immediately after the execution of any user procedure.
  4261.  
  4262.        User procedures should only be executed when the stack contains only user
  4263.        objects; the CK<n>NOLASTWD (usually CK0NOLASTWD)
  4264.        is executed immediately after the user procedure
  4265.        to update the stack save mark to protect the stack results of the procedure.
  4266.        This is usually done in conjunction with 0LASTOWDOB!, which clears
  4267.        the command save done by the last CK<n> executed within the user
  4268.        procedure, so that that command is not identified as the culprit for
  4269.        any subsequent errors.  Useful words for these purposes are
  4270.  
  4271.                AtUserStack     which is :: CK0NOLASTWD 0LASTOWDOB! ;
  4272.                CK1NoBlame      which is :: 0LASTOWDOB! CK1NOLASTWD ;
  4273.  
  4274.        For objects that take a stack specified number of arguments, the analogs
  4275.        to CK<n> and CK<n>NOLASTWD are CKN and CKNNOLASTWD.  Both words check
  4276.        for a real number in level 1, then check if there are that many additional
  4277.        objects on the stack.  The stack is marked at level 2, and only the
  4278.        real number is restore by LAST ARG.
  4279.  
  4280.  
  4281.  
  4282.  
  4283.  
  4284.  
  4285.  
  4286.  
  4287.  
  4288.  
  4289.                                  Page 62
  4290.  
  4291.  
  4292.  
  4293.  
  4294.  
  4295.  
  4296.        14.2  Dispatching on Argument Type
  4297.  
  4298.        The words CK&DISPATCH1 and CK&DISPATCH0 provide a dispatch-
  4299.        by-type mechanism (the CK<n>&Dispatch words include the same
  4300.        mechanism, so the following discussion applies to them as
  4301.        well), that provides straightforward branching according to
  4302.        the object types of up to five arguments at a time.  Each
  4303.        word is followed by an indefinite number of pairs of object.
  4304.        Each pair consists of a binary integer or object pointer to
  4305.        a binary integer, followed by any object or object pointer
  4306.        (exclusive use of object pointers guarantees the fastest
  4307.        dispatching):
  4308.  
  4309.          ...
  4310.          CK&DISPATCH1   #type1 action1                  #type2
  4311.        action2                   ...                   #typen
  4312.        action3
  4313.          ;
  4314.  
  4315.        The object-pair sequence must be terminated by a SEMI (;).
  4316.  
  4317.        CK&DISPATCH1 proceeds as follows: For each typei, from type1
  4318.        to typen, if typei matches the stack configuration then
  4319.        execute actioni, discarding the rest of word containing
  4320.        CK&DISPATCH1.  If no match is found, report the error "Bad
  4321.        Argument Type".
  4322.  
  4323.        If a complete pass is made through the table without a
  4324.        successful match, the CK&DISPATCH1 makes a second pass
  4325.        through the table, this time stripping any tags from stack
  4326.        objects and matching the remaining objects against the
  4327.        required types.
  4328.  
  4329.  
  4330.  
  4331.  
  4332.  
  4333.  
  4334.  
  4335.  
  4336.  
  4337.  
  4338.  
  4339.  
  4340.  
  4341.  
  4342.  
  4343.  
  4344.  
  4345.  
  4346.  
  4347.  
  4348.  
  4349.  
  4350.  
  4351.  
  4352.  
  4353.  
  4354.  
  4355.                                  Page 63
  4356.  
  4357.  
  4358.  
  4359.  
  4360.  
  4361.  
  4362.        The word CK&DISPATCH0 does not perform the second pass which
  4363.        strips tags.  This word should only be used where it is
  4364.        important to find a tagged object.  The general behavior of
  4365.        the HP 48 is to regard tags as being auxiliary to the tagee,
  4366.        and thus CK&DISPATCH1 should be used in most cases.
  4367.  
  4368.        A binary integer typei is nominally encoded as follows:
  4369.  
  4370.                #nnnnn
  4371.                 |||||
  4372.                 ||||+-- Level 1 argument type
  4373.                 |||+--- Level 2 argument type
  4374.                 ||+---- Level 3 argument type
  4375.                 |+----- Level 4 argument type
  4376.                 +------ Level 5 argument type
  4377.  
  4378.        Each "n" is a hexadecimal digit representing an object type,
  4379.        as shown in the table below.  Thus #00011 represents two
  4380.        real numbers; #000A0 indicates a symbolic class object
  4381.        (symb, id, or lam) in level 2 and any type of object in
  4382.        level 1.  There are also two-digit object type numbers,
  4383.        ending in F; use of any of these consequently reduces the
  4384.        total number of arguments that can be encoded in a single
  4385.        typei integer.  For example, #13F4F represents a real number
  4386.        in level 3, an extended real in level 2, and an extended
  4387.        complex in level 1.
  4388.  
  4389.        The following table shows the hex digit values for each
  4390.        argument type.  The column "# name" shows the object pointer
  4391.        name for the corresponding binary integer that may be used
  4392.        for a single argument function.  The "Binary Integers"
  4393.        chapter contains a list of built-in binary integers that may
  4394.        be used for various common two-argument combinations.
  4395.  
  4396.                Value   Argument           # name   User TYPE
  4397.                -----   ----------------   ------   ---------
  4398.                  0     Any Object          any
  4399.                  1     Real Number         real         0
  4400.                  2     Complex Number      cmp          1
  4401.                  3     Character String    str          2
  4402.                  4     Array               arry       3,4
  4403.                  5     List                list         5
  4404.                  6     Global Name         idnt         6
  4405.                  7     Local Name          lam          7
  4406.                  8     Secondary           seco         8
  4407.                  9     Symbolic            symb         9
  4408.                  A     Symbolic Class      sym      6,7,9
  4409.                  B     Hex String          hxs         10
  4410.                  C     Graphics Object     grob        11
  4411.                  D     Tagged Object       TAGGED      12
  4412.                  E     Unit Object         unitob      13
  4413.                 0F     ROM Pointer                     14
  4414.                 1F     Binary Integer                  20
  4415.                 2F     Directory                       15
  4416.                 3F     Extended Real                   21
  4417.                 4F     Extended Complex                22
  4418.  
  4419.  
  4420.  
  4421.                                  Page 64
  4422.  
  4423.  
  4424.  
  4425.  
  4426.                 5F     Linked Array                    23
  4427.                 6F     Character                       24
  4428.                 7F     Code Object                     25
  4429.                 8F     Library                         16
  4430.                 9F     Backup                          17
  4431.                 AF     Library Data                    26
  4432.                 BF     External object1                27
  4433.                 CF     External object2                28
  4434.                 DF     External object3                29
  4435.                 EF     External object4                30
  4436.  
  4437.  
  4438.  
  4439.  
  4440.  
  4441.  
  4442.  
  4443.  
  4444.  
  4445.  
  4446.  
  4447.  
  4448.  
  4449.  
  4450.  
  4451.  
  4452.  
  4453.  
  4454.  
  4455.  
  4456.  
  4457.  
  4458.  
  4459.  
  4460.  
  4461.  
  4462.  
  4463.  
  4464.  
  4465.  
  4466.  
  4467.  
  4468.  
  4469.  
  4470.  
  4471.  
  4472.  
  4473.  
  4474.  
  4475.  
  4476.  
  4477.  
  4478.  
  4479.  
  4480.  
  4481.  
  4482.  
  4483.  
  4484.  
  4485.  
  4486.  
  4487.                                  Page 65
  4488.  
  4489.  
  4490.  
  4491.  
  4492.        14.3  Examples
  4493.  
  4494.        Built-in commands and other words provide good examples of
  4495.        the check-and- dispatching scheme.  The following is the
  4496.        definition of the user command STO:
  4497.  
  4498.        :: CK2&Dispatch
  4499.            THIRTEEN  XEQXSTO                    ( 2:any object 1:tagged object)
  4500.            SIX       :: STRIPTAGSl2 ?STO_HERE ; ( 2:any        1:id )
  4501.            SEVEN     :: STRIPTAGSl2 STO ;       ( 2:any        1:lam )
  4502.            NINE      :: STRIPTAGSl2 SYMSTO ;    ( 2:any        1:symb )
  4503.            # 000c8   PICTSTO                    ( 2:grob       1:program [PICT] )
  4504.            # 009f1   LBSTO                      ( 2:backup ob  1:real number )
  4505.            # 008f1   LBSTO                      ( 2:library    1:real number )
  4506.        ;
  4507.  
  4508.        Since STO is a command, it starts with CK2&Dispatch, which
  4509.        verifies that there are two arguments present, saves those
  4510.        arguments and the command STO for error handling, then
  4511.        dispatches to one of the action objects listed in the
  4512.        dispatch table.  If the level one object is tagged, STO
  4513.        dispatches to the word XEQSTO.  For a global name (id), STO
  4514.        executes :: STRIPTAGSl2 ?STO_HERE ;, which is directly
  4515.        embedded in the STO program.  And so forth, down to the last
  4516.        choice, which is a dispatch to LBSTO when the arguments are
  4517.        a library in level 2, and a real number in level 1.
  4518.  
  4519.        The TYPE command provides an example of dispatching at a
  4520.        point other than the start of a command.  TYPE is a command,
  4521.        but its argument counting and argument type dispatching are
  4522.        separated so that the latter part can be called by other
  4523.        system words that don't want to mark the stack:
  4524.  
  4525.        ::
  4526.          CK1
  4527.          :: CK&DISPATCH0
  4528.                real             %0
  4529.                cmp              %1
  4530.                str              %2
  4531.                arry             XEQTYPEARRY
  4532.                list             %5
  4533.                id               %6
  4534.                lam              %7
  4535.                seco             TYPESEC ( 8, 18, or 19 )
  4536.                symb             %9
  4537.                hxs              %10
  4538.                grob             % 11
  4539.                TAGGED           % 12
  4540.                unitob           % 13
  4541.                rompointer       % 14
  4542.                THIRTYONE ( # )  % 20
  4543.                rrp              % 15
  4544.                # 3F ( %% )      % 21
  4545.                # 4F ( C%% )     % 22
  4546.                # 5F ( LNKARRY ) % 23
  4547.                # 6F ( CHR )     % 24
  4548.                # 7F ( CODE )    % 25
  4549.                library          % 16
  4550.  
  4551.  
  4552.  
  4553.                                  Page 66
  4554.  
  4555.  
  4556.  
  4557.  
  4558.  
  4559.  
  4560.                backup           % 17
  4561.                # AF             % 26 ( Library Data )
  4562.                any              % 27 ( external )
  4563.          ;
  4564.          SWAPDROP
  4565.        ;
  4566.  
  4567.        CK&DISPATCH0 is used here, although CK&DISPATCH1 would work
  4568.        as well since tagged objects are explicitly listed in the
  4569.        dispatch table.  Notice also that the last typei is "any",
  4570.        meaning that type 27 is returned for any object type not
  4571.        previously listed.
  4572.  
  4573.        The "inner" program (starting after the CK1) is the body of
  4574.        the system word XEQTYPE.
  4575.  
  4576.  
  4577.  
  4578.  
  4579.  
  4580.  
  4581.  
  4582.  
  4583.  
  4584.  
  4585.  
  4586.  
  4587.  
  4588.  
  4589.  
  4590.  
  4591.  
  4592.  
  4593.  
  4594.  
  4595.  
  4596.  
  4597.  
  4598.  
  4599.  
  4600.  
  4601.  
  4602.  
  4603.  
  4604.  
  4605.  
  4606.  
  4607.  
  4608.  
  4609.  
  4610.  
  4611.  
  4612.  
  4613.  
  4614.  
  4615.  
  4616.  
  4617.  
  4618.  
  4619.                                  Page 67
  4620.  
  4621.  
  4622.  
  4623.  
  4624.        15.  Loop Control Structures
  4625.  
  4626.        Two types of looping structures are available - indefinite
  4627.        loops and definite loops.
  4628.  
  4629.  
  4630.        15.1  Indefinite Loops
  4631.  
  4632.        Indefinite loops are constructed from combinations of the
  4633.        following RPL words:
  4634.  
  4635.           BEGIN ( --> )
  4636.           Copies the interpreter pointer (RPL variable I) onto the return stack.
  4637.           Also called IDUP.
  4638.  
  4639.           UNTIL ( flag --> )
  4640.           If flag is TRUE, drops the top pointer on the return stack, otherwise
  4641.           copies that pointer to the interpreter pointer.
  4642.  
  4643.           WHILE ( flag --> )
  4644.           If the flag is TRUE, then does nothing.  Else drops the first pointer from
  4645.           the return stack, and skips the interpreter pointer past the next two
  4646.           objects.
  4647.  
  4648.           REPEAT ( --> )
  4649.              -->
  4650.           Copies the first pointer on the return stack to the interpreter pointer.
  4651.  
  4652.           AGAIN ( --> )
  4653.  
  4654.  
  4655.        The WHILE loop is an indefinite loop:
  4656.  
  4657.                BEGIN
  4658.                  <test clause>
  4659.                WHILE
  4660.                  <loop object>
  4661.                REPEAT
  4662.  
  4663.  
  4664.        The WHILE loop executes <test clause>, and if the result is
  4665.        the system flag TRUE, executes the <loop object> and
  4666.        repeats; otherwise it exits to past the REPEAT.  The WHILE
  4667.        loop never executes if the first run of <test clause>
  4668.        returns FALSE.
  4669.  
  4670.        The action of WHILE requires <loop object> to be a single
  4671.        object.  However, the RPL compiler automatically combines
  4672.        multiple objects between WHILE and REPEAT into a program
  4673.        object, so that
  4674.  
  4675.                BEGIN
  4676.                  <test clause>
  4677.                WHILE
  4678.                  ob1 ... obn
  4679.                REPEAT
  4680.  
  4681.        is actually compiled as
  4682.  
  4683.  
  4684.  
  4685.                                  Page 68
  4686.  
  4687.  
  4688.  
  4689.  
  4690.  
  4691.  
  4692.                BEGIN
  4693.                  <test clause>
  4694.                WHILE
  4695.                  :: ob1 ... obn ;
  4696.                REPEAT
  4697.  
  4698.  
  4699.        Another common indefinite loop is the BEGIN...UNTIL:
  4700.  
  4701.                BEGIN
  4702.                  <loop clause>
  4703.                UNTIL
  4704.  
  4705.  
  4706.        This loop executes at least once, as opposed to the WHILE
  4707.        loop, which does not execute its loop object if the initial
  4708.        test is false.  The word UNTIL expects a flag (TRUE or
  4709.        FALSE).
  4710.  
  4711.        The BEGIN...AGAIN loop has no test:
  4712.  
  4713.                BEGIN
  4714.                  <loop clause>
  4715.                AGAIN
  4716.  
  4717.  
  4718.        Terminating this loop requires an error event, or a direct
  4719.        manipulation of the return stack.
  4720.  
  4721.  
  4722.  
  4723.  
  4724.  
  4725.  
  4726.  
  4727.  
  4728.  
  4729.  
  4730.  
  4731.  
  4732.  
  4733.  
  4734.  
  4735.  
  4736.  
  4737.  
  4738.  
  4739.  
  4740.  
  4741.  
  4742.  
  4743.  
  4744.  
  4745.  
  4746.  
  4747.  
  4748.  
  4749.  
  4750.  
  4751.                                  Page 69
  4752.  
  4753.  
  4754.  
  4755.  
  4756.        15.2  Definite Loops
  4757.  
  4758.        Definite loops with a loop counter are achieved in RPL by
  4759.        means of the DO Loop.  The word DO takes two binary integer
  4760.        objects from the stack, and stores the top object as the
  4761.        index and the other as the stopping value in a special
  4762.        DoLoop environment.  DO also copies the interpreter pointer
  4763.        onto the return stack.  DoLoop environments are stacked, so
  4764.        that they can be nested indefinitely.  The topmost index is
  4765.        recalled by INDEX@; the index in the second environment by
  4766.        JINDEX@.  The topmost stopping value is available via
  4767.        ISTOP@.
  4768.  
  4769.        DO's counterparts are LOOP and +LOOP.  LOOP increments the
  4770.        index value in the topmost DoLoop environment; then, if the
  4771.        (new) value is greater than or equal to the stopping value,
  4772.        LOOP drops the top pointer from the return stack and removes
  4773.        the topmost DoLoop environment.  Otherwise, LOOP acts copies
  4774.        the top return stack pointer to the interpreter pointer.
  4775.        The standard form of a DoLoop is
  4776.  
  4777.                     stop start DO <loop clause> LOOP,
  4778.  
  4779.        which executes <loop clause> for each value of an index from
  4780.        start to stop-1.
  4781.  
  4782.        +LOOP is similar to LOOP, except that it takes a binary
  4783.        integer from the stack and increments the loop counter by
  4784.        that amount rather than 1.
  4785.  
  4786.  
  4787.        15.2.1  Provided_Words
  4788.  
  4789.        The following words are provided for use with DO loops.
  4790.        Words marked with * are not recognized as special by the RPL
  4791.        compiler, so you should include compiler directives to
  4792.        prevent warning messages.  For example, #1+_ONE_DO can be
  4793.        followed by (DO) which matches the following LOOP for the
  4794.        sake of the compiler but does not generate any compiled
  4795.        code.
  4796.  
  4797.        #1+_ONE_DO *    ( #finish --> )
  4798.                          Equivalent to #1+ ONE DO; commonly used to execute a loop
  4799.                          #finish times.
  4800.        DO              ( #finish #start --> )
  4801.                          Begins DO loop
  4802.        DROPLOOP *      ( ob --> )
  4803.                          Performs DROP, then LOOP
  4804.        DUP#0_DO *      ( # --> # )
  4805.                          Begins # ... #0 DO loop
  4806.        DUPINDEX@       ( ob --> ob ob #index )
  4807.                          Does DUP, then returns value of index in topmost DoLoop env.
  4808.        ExitAtLOOP      ( --> )
  4809.                          Stores zero in stopping value of topmost DoLoop environment
  4810.        INDEX@          ( --> #index )
  4811.                          Returns index of topmost DoLoop environment
  4812.        INDEX@#-        ( # --> #' )
  4813.                          Subtracts index value of topmost
  4814.  
  4815.  
  4816.  
  4817.                                  Page 70
  4818.  
  4819.  
  4820.  
  4821.  
  4822.  
  4823.  
  4824.                          DoLoop environment from #
  4825.        INDEXSTO        ( # --> )
  4826.                          Stores # as index of top DoLoop environment
  4827.        ISTOP@          ( --> #stop )
  4828.                          Returns stop value of the topmost DoLoop environment
  4829.        ISTOPSTO        ( # --> )
  4830.                          Stores new stop value in the topmost DoLoop environment
  4831.        JINDEX@         ( --> #index )
  4832.                          Returns index of second DoLoop environment
  4833.        LOOP            ( --> )
  4834.                          End of loop structure
  4835.        NOT_UNTIL *     ( flag --> )
  4836.                          End of loop structure
  4837.        ONE_DO *        ( #finish --> )
  4838.                          Begins #1...#finish DO loop
  4839.        OVERINDEX@      ( ob1 ob2 --> ob1 ob2 ob1 #index )
  4840.                          Does OVER, then returns value of
  4841.                          index in topmost DoLoop environment
  4842.        SWAPINDEX@      ( ob1 ob2 --> ob2 ob1 #index )
  4843.                          Does SWAP, then returns value of index in topmost
  4844.                          DoLoop environment
  4845.        SWAPLOOP *      ( ob1 ob2 --> ob2 ob1 )
  4846.                          Does SWAP, then LOOP
  4847.        ZEROISTOPSTO    ( --> )
  4848.                          Stores zero as the stop value in the topmost DoLoop
  4849.                          environment
  4850.        ZERO_DO *       ( #finish --> )
  4851.                          Begins DO loop from #0 to #finish
  4852.        toLEN_DO        ( {list} --> {list} )
  4853.                          Begins DO loop from #1 of elements in list to stop value
  4854.                          #number-of-elements+1.
  4855.  
  4856.        15.2.2  Examples
  4857.  
  4858.                FIVE ZERO
  4859.                DO
  4860.                  INDEX@
  4861.                LOOP
  4862.  
  4863.        This returns the values:
  4864.  
  4865.                #00000 #00001 #00002 #00003 #00004
  4866.  
  4867.        The following sequence displays each of the elements (up to 8) of
  4868.        a list of strings on a separate display line.
  4869.  
  4870.                DUPLENCOMP
  4871.                ONE_DO (DO)
  4872.                  DUP INDEX@ NTHCOMPDROP
  4873.                  INDEX@ DISPN
  4874.                LOOP
  4875.  
  4876.  
  4877.  
  4878.  
  4879.  
  4880.  
  4881.  
  4882.  
  4883.                                  Page 71
  4884.  
  4885.  
  4886.  
  4887.  
  4888.  
  4889.  
  4890.        A more compact version uses toLEN_DO:
  4891.  
  4892.                toLEN_DO (DO)
  4893.                  DUP INDEX@ NTHCOMPDROP
  4894.                  INDEX@ DISPN
  4895.                LOOP
  4896.  
  4897.        Another version is slightly faster, since it avoids repeated extraction
  4898.        of list elements:
  4899.  
  4900.                INNERCOMP
  4901.                #1+_ONE_DO (DO)
  4902.                  INDEX@ DISPN
  4903.                LOOP
  4904.  
  4905.        This version displays the elements in reverse order relative to the previous
  4906.        versions.
  4907.  
  4908.  
  4909.  
  4910.  
  4911.  
  4912.  
  4913.  
  4914.  
  4915.  
  4916.  
  4917.  
  4918.  
  4919.  
  4920.  
  4921.  
  4922.  
  4923.  
  4924.  
  4925.  
  4926.  
  4927.  
  4928.  
  4929.  
  4930.  
  4931.  
  4932.  
  4933.  
  4934.  
  4935.  
  4936.  
  4937.  
  4938.  
  4939.  
  4940.  
  4941.  
  4942.  
  4943.  
  4944.  
  4945.  
  4946.  
  4947.  
  4948.  
  4949.                                  Page 72
  4950.  
  4951.  
  4952.  
  4953.  
  4954.        16.  Error Generation & Trapping
  4955.  
  4956.        The RPL error handling sub-system is invoked by execution of
  4957.        the word ERRJMP, that is, when a procedure class object
  4958.        wishes to generate an error, it executes ERRJMP (probably
  4959.        after setting the values of ERROR and ERRNAME). The
  4960.        mechanics of ERRJMP will be described later.
  4961.  
  4962.  
  4963.        16.1  Trapping: ERRSET and ERRTRAP
  4964.  
  4965.        RPL provides procedure objects with the capability to
  4966.        intercept execution of the error handling sub-system, that
  4967.        is, trap an error generated by an object which is lower on
  4968.        the threaded order. This capability is made available via
  4969.        the built-in objects ERRSET and ERRTRAP used in the
  4970.        following way:
  4971.  
  4972.        :: ... ERRSET <suspect object> ERRTRAP <if-error object> ... ;
  4973.  
  4974.        In the above, an error generated by <suspect object> is to
  4975.        be trapped.  <if-error object> denotes the object to be
  4976.        executed if <suspect object> generates an error. The exact
  4977.        algorithm is: If <suspect object> generates an error, then
  4978.        continue execution at <if-error object>; else, continue
  4979.        execution beyond <if-error object>.
  4980.  
  4981.        The action of <if-error object> is completely flexible; when
  4982.        <if-error object> gets control, it may examine the values of
  4983.        ERROR and ERRNAME to determine whether or not it is even
  4984.        concerned with the current error. If not, it may simply re-
  4985.        start the sub-system by executing ERRJMP. If so, it may
  4986.        decide to handle the error, that is, clear both ERROR and
  4987.        ERRNAME and NOT restart the sub-system. It may also disable
  4988.        execution of the remainder of the program (perhaps via
  4989.        RDROP).
  4990.  
  4991.        Note that throughout (normal) execution of <suspect object>,
  4992.        an object pointer to the following ERRTRAP is somewhere in
  4993.        the runstream.
  4994.  
  4995.  
  4996.        16.2  Action of ERRJMP
  4997.  
  4998.        When an RPL procedure wants to initiate an error, it
  4999.        executes ERRJMP, which the error handling sub-system.
  5000.        ERRJMP cycles through the RUNSTREAM from the interpreter
  5001.        pointer I up through the return stack searching for an error
  5002.        trap. Specifically, ERRJMP removes pending program bodies
  5003.        from the RUNSTREAM until it finds one whose first element is
  5004.        an object pointer addressing ERRTRAP (this program body may
  5005.        correspond to a return stack level as well as the
  5006.        interpreter pointer I). It then SKIPs over the object
  5007.        pointer to ERRTRAP and continues execution beyond it (at the
  5008.        <if-error object>).
  5009.  
  5010.        Note, therefore, that ERRTRAP is only executed if <suspect
  5011.        object> terminates without generating an error; in this
  5012.  
  5013.  
  5014.  
  5015.                                  Page 73
  5016.  
  5017.  
  5018.  
  5019.  
  5020.  
  5021.  
  5022.        case, ERRTRAP will, among other things, SKIP <if-error
  5023.        object> and continue execution beyond it.
  5024.  
  5025.        If a procedure is not merely passing along an error that it
  5026.        did not initiate, its invokation of ERRJMP should be
  5027.        preceded by execution of ERRORSTO, which stores an error
  5028.        number in a special system location.  ERROR@ returns the
  5029.        stored error number, which error traps can use to determine
  5030.        if they want to handle a particular error.  The error number
  5031.        is stored and returned as a binary integer; the high-order
  5032.        12 bits of the number represent the Library ID of the
  5033.        library containing the error message, and the remaining bits
  5034.        indicate the error number within the library's message
  5035.        table.
  5036.  
  5037.  
  5038.        16.3  The Protection Word
  5039.  
  5040.        Each temporary environment and each DoLoop environment has a
  5041.        protection word. The sole reason for the existence of this
  5042.        protection word is to allow the error handling sub-system to
  5043.        distinguish temporary and DoLoop environments that were in
  5044.        existence at the time an error trap was set from those which
  5045.        came into being after the error trap was set. For example,
  5046.        consider the following:
  5047.  
  5048.        ::
  5049.          ...
  5050.          { NULLLAM } BIND
  5051.          ...
  5052.          TEN ZERO DO
  5053.            ERRSET ::
  5054.              ...
  5055.              { NULLLAM } BIND
  5056.              ...
  5057.              FIVE TWO DO
  5058.                <procedure>
  5059.              LOOP
  5060.              ABND
  5061.            ;
  5062.            ERRTRAP
  5063.              :: "Procedure Failed" FlashMsg ;
  5064.          LOOP
  5065.          ...
  5066.          ABND
  5067.          ...
  5068.        ;
  5069.  
  5070.        If <procedure> generates an error, then this error will be
  5071.        trapped by the word or secondary following ERRTRAP.
  5072.        However, the inner DoLoop and temporary environments must be
  5073.        deleted so that the outer procedure has available the
  5074.        correct DoLoop parameters and local variables.  The
  5075.        protection word serves to abet this function.
  5076.  
  5077.        ERRSET increments the protection word in the topmost
  5078.  
  5079.  
  5080.  
  5081.                                  Page 74
  5082.  
  5083.  
  5084.  
  5085.  
  5086.  
  5087.  
  5088.        temporary environment and the topmost DoLoop environment.
  5089.        These topmost environments therefore have a non-zero
  5090.        protection word. (DO and BIND always initialize the
  5091.        protection word to zero).
  5092.  
  5093.        ERRTRAP and ERRJMP delete temporary and DoLoop environments
  5094.        (from the first to the last) until, in both cases, they find
  5095.        one with a non-zero protection word, which is then
  5096.        decremented. Therefore, whenever either ERRJMP executes at
  5097.        <if-error object> or ERRTRAP executes past <if-error
  5098.        object>, only temporary and DoLoop environments which
  5099.        existed at the ERRSET will be present.
  5100.  
  5101.        Note especially that the protection word is more than just a
  5102.        switch so as to allow a practically indeterminant level of
  5103.        nesting of error traps.
  5104.  
  5105.        The example above is actually a poorly formed error trap -
  5106.        the code should actually determine what the error was, and
  5107.        take action accordingly.  The word ERROR@ may be used to
  5108.        recall which error occurred.  The error numbers correspond
  5109.        to the message numbers - see the message table in appendix A
  5110.        of the "HP48 Programmers Reference Manual".
  5111.  
  5112.  
  5113.        16.4  Error Words
  5114.  
  5115.        The following words are provided for error management:
  5116.  
  5117.        ABORT           ( --> )
  5118.                          Does ERRORCLR and ERRJMP
  5119.        DO#EXIT         ( msg# --> )
  5120.                          Stores a new error number and executes ERRJMP;
  5121.                          also executes AtUserStack
  5122.                          Puts the object ERRJMP on the stack
  5123.        ERRBEEP         ( --> )
  5124.                          Generates an error beep
  5125.        ERRJMP          ( --> )
  5126.                          Invokes error handling subsystem
  5127.        ERROR@          ( --> # )
  5128.                          Returns the current error number
  5129.        ERRORCLR        ( --> )
  5130.                          Stores zero as the error number
  5131.        ERROROUT        ( # --> )
  5132.                          Stores a new error number and does ERRJMP
  5133.        ERRORSTO        ( # --> )
  5134.                          Stores new error number
  5135.        ERRTRAP         ( --> )
  5136.                          Skips next object in runstream.
  5137.  
  5138.  
  5139.  
  5140.  
  5141.  
  5142.  
  5143.  
  5144.  
  5145.  
  5146.  
  5147.                                  Page 75
  5148.  
  5149.  
  5150.  
  5151.  
  5152.  
  5153.  
  5154.        17.  Test and Control
  5155.  
  5156.        This chapter reviews words related to the flow of control:
  5157.        conditional and unconditional branches and the associated
  5158.        test words.
  5159.  
  5160.  
  5161.        17.1  Flags and Tests
  5162.  
  5163.        TRUE and FALSE are built-in objects that are recognized by
  5164.        test words as flags for branching decisions. The following
  5165.        words create or combine flags:
  5166.  
  5167.        AND ( flag1 flag2  --> flag )
  5168.          If flag1 and flag2 are both TRUE then TRUE else FALSE.
  5169.  
  5170.        FALSE ( --> FALSE )
  5171.          Puts the FALSE flag on the stack.
  5172.  
  5173.        FALSETRUE       ( --> FALSE TRUE )
  5174.  
  5175.        FalseFalse      ( --> FALSE FALSE )
  5176.  
  5177.        OR ( flag1 flag2  --> flag )
  5178.          If either flag1 or flag2 is TRUE then TRUE else FALSE.
  5179.  
  5180.        ORNOT           ( flag1 flag2 --> flag3 )
  5181.          Logical OR followed by logical NOT.
  5182.  
  5183.        NOT ( flag --> flag' )
  5184.          If flag is TRUE then FALSE else TRUE.
  5185.  
  5186.        NOTAND          ( flag1 flag2 --> flag3 )
  5187.          Logical NOT, then logical AND.
  5188.  
  5189.        ROTAND          ( flag1 ob flag2 --> ob flag3 )
  5190.          Does ROT, then logical AND.
  5191.  
  5192.        TRUE            ( --> TRUE )
  5193.          Puts the TRUE flag on the stack.
  5194.  
  5195.        TrueFalse       ( --> TRUE FALSE )
  5196.  
  5197.        TrueTrue        ( --> TRUE TRUE )
  5198.  
  5199.        XOR             ( flag1 flag2  --> flag )
  5200.          If both flag1 and flag2 are either TRUE or FALSE then FALSE, else TRUE.
  5201.  
  5202.        COERCEFLAG      ( TRUE --> %1 )
  5203.                        ( FALSE --> %0 )
  5204.          Converts a system flag to a real number flag.
  5205.  
  5206.  
  5207.  
  5208.  
  5209.  
  5210.  
  5211.  
  5212.  
  5213.                                  Page 76
  5214.  
  5215.  
  5216.  
  5217.  
  5218.  
  5219.  
  5220.        17.1.1  General_Object_Tests
  5221.  
  5222.        The following words test object type and equality:
  5223.  
  5224.        EQ              ( ob1 ob2 --> flag )
  5225.          If objects ob1 and ob2 are the same object, i.e.  occupy the same
  5226.          physical space in memory, then TRUE else FALSE.
  5227.  
  5228.        EQUAL           ( ob1 ob2 --> flag )
  5229.          where ob1 and ob2 are not primitive code objects. If objects ob1 and
  5230.          ob2 are the same then TRUE else FALSE (this word is the system
  5231.          equivalent of the user RPL command SAME)
  5232.  
  5233.        2DUPEQ          ( ob1 ob2 --> ob1 ob2 flag )
  5234.          Returns TRUE if ob1 and ob2 have  the same physical address.
  5235.  
  5236.        EQOR            ( flag1 ob1 ob2 --> flag2 )
  5237.          Does EQ, then logical OR.
  5238.  
  5239.        EQUALOR         ( flag1 ob1 ob2 --> flag2 )
  5240.          Does EQUAL, the logical OR.
  5241.  
  5242.        EQOVER          ( ob1 ob2 ob3 --> ob1 flag ob1 )
  5243.          Does EQ, then OVER.
  5244.  
  5245.        EQUALNOT        ( ob1 ob2 --> flag )
  5246.          Returns FALSE if ob1 is equal to ob2.
  5247.  
  5248.        The following words test an object's type.  Words of the
  5249.        form TYPE...?  have a stack diagram ( ob --> flag ); those
  5250.        of the form DTYPE...? or DUPTYPE...? duplicate the object
  5251.        first ( ob --> ob flag ).
  5252.  
  5253.        Test Words              Object type
  5254.  
  5255.        TYPEARRY?               array
  5256.        DTYPEARRY?
  5257.        DUPTYPEARRY?
  5258.  
  5259.        TYPEBINT?               binary integer
  5260.        DUPTYPEBINT?
  5261.  
  5262.        TYPECARRY?              complex array
  5263.  
  5264.        TYPECHAR?               character
  5265.        DUPTYPECHAR?
  5266.  
  5267.        TYPECMP?                complex number
  5268.        DUPTYPECMP?
  5269.  
  5270.        TYPECOL?                program
  5271.        DTYPECOL?
  5272.        DUPTYPECOL?
  5273.  
  5274.  
  5275.  
  5276.  
  5277.  
  5278.  
  5279.                                  Page 77
  5280.  
  5281.  
  5282.  
  5283.  
  5284.  
  5285.  
  5286.        TYPECSTR?               string
  5287.        DTYPECSTR?
  5288.        DUPTYPECSTR?
  5289.  
  5290.        TYPEEXT?                unit
  5291.        DUPTYPEEXT?
  5292.  
  5293.        TYPEGROB?               graphics object
  5294.        DUPTYPEGROB?
  5295.  
  5296.        TYPEHSTR?               hex string
  5297.        DUPTYPEHSTR?
  5298.  
  5299.        TYPEIDNT?               identifier (global name)
  5300.        DUPTYPEIDNT?
  5301.  
  5302.        TYPELAM?                temporary identifier (local name)
  5303.        DUPTYPELAM?
  5304.  
  5305.        TYPELIST?               list
  5306.        DTYPELIST?
  5307.        DUPTYPELIST?
  5308.  
  5309.        TYPERARRY?              real array
  5310.  
  5311.        TYPEREAL?               real number
  5312.        DTYPEREAL?
  5313.        DUPTYPEREAL?
  5314.  
  5315.        TYPEROMP?               ROM pointer (XLIB name)
  5316.        DUPTYPEROMP?
  5317.  
  5318.        TYPERRP?                Directory
  5319.        DUPTYPERRP?
  5320.  
  5321.        TYPESYMB?               Symbolic
  5322.        DUPTYPESYMB?
  5323.  
  5324.        TYPETAGGED?             Tagged
  5325.        DUPTYPETAG?
  5326.  
  5327.  
  5328.        17.1.2  Binary_Integer_Comparisons
  5329.  
  5330.        The following words compare binary integers, returning TRUE
  5331.        or FALSE. Equality is tested in the sense of EQUAL (not EQ).
  5332.        Ordering treats all binary integers as unsigned.  Some of
  5333.        these words are also available in combination with case
  5334.        words (see below).
  5335.  
  5336.        #=      ( # #' --> flag )       TRUE if # = #'.
  5337.  
  5338.        #<>     ( # #' --> flag )       TRUE if # <> #' (not equal).
  5339.  
  5340.        #0=     ( # --> flag )          TRUE if # = 0
  5341.  
  5342.  
  5343.  
  5344.  
  5345.                                  Page 78
  5346.  
  5347.  
  5348.  
  5349.  
  5350.  
  5351.  
  5352.        #0<>    ( # --> flag )          TRUE if # <> 0
  5353.  
  5354.        #<      ( # #' --> flag )       TRUE if # < #'
  5355.  
  5356.        #>      ( # #' --> flag )       TRUE if # > #'
  5357.  
  5358.        2DUP#<  ( # #' --> # #' flag ) TRUE if # < #'
  5359.  
  5360.        2DUP#=  ( # #' --> # #' flag ) TRUE if # = #'
  5361.  
  5362.        DUP#0=  ( # --> # flag )        TRUE if # = #0
  5363.  
  5364.        DUP#1=  ( # --> # flag )        TRUE if # = #1
  5365.  
  5366.        DUP#0<> ( # --> # flag )        TRUE if # <> #0
  5367.  
  5368.        DUP#1=  ( # --> # flag )        TRUE if # = #1
  5369.  
  5370.        DUP#<7  ( # --> # flag )        TRUE if # < #7
  5371.  
  5372.        DUP%0=  ( % --> % flag )        TRUE if % = %0
  5373.  
  5374.        ONE#>   ( # --> flag )          TRUE if # > #1
  5375.  
  5376.        ONE_EQ  ( # --> flag )          TRUE if # is ONE
  5377.  
  5378.        OVER#>  ( # #' --> # flag )     TRUE if # > #'
  5379.  
  5380.        OVER#0= ( # ob --> # ob flag )  TRUE if # is #0
  5381.  
  5382.        OVER#<  ( # #' --> # flag )     TRUE if # > #'
  5383.  
  5384.        OVER#=  ( # #' --> # flag )     TRUE if # = #'
  5385.  
  5386.        OVER#>  ( # #' --> # flag )     TRUE if # < #'
  5387.  
  5388.  
  5389.        17.1.3  Decimal_Number_Tests
  5390.  
  5391.        The following words compare real, extended real, and complex
  5392.        numbers, returning TRUE or FALSE.
  5393.  
  5394.        %<      ( % %' --> flag )       TRUE if % < %'
  5395.  
  5396.        %<=     ( % %' --> flag )       TRUE if % <= %'
  5397.  
  5398.        %<>     ( % %' --> flag )       TRUE if % <> %'
  5399.  
  5400.        %=      ( % %' --> flag )       TRUE if % = %'
  5401.  
  5402.        %>      ( % %' --> flag )       TRUE if % > %'
  5403.  
  5404.        %>=     ( % %' --> flag )       TRUE if % >= %'
  5405.  
  5406.        %0<     ( % --> flag )          TRUE if % < 0
  5407.  
  5408.  
  5409.  
  5410.  
  5411.                                  Page 79
  5412.  
  5413.  
  5414.  
  5415.  
  5416.  
  5417.  
  5418.        %0<>    ( % --> flag )          TRUE if % <> 0
  5419.  
  5420.        %0=     ( % --> flag )          TRUE if % = 0
  5421.  
  5422.        %0>     ( % --> flag )          TRUE if % > 0
  5423.  
  5424.        %0>=    ( % --> flag )          TRUE if % >= 0
  5425.  
  5426.  
  5427.        %%0<=   ( %% %%' --> flag )     TRUE if %% <= %%'
  5428.  
  5429.        %%0<>   ( %% --> flag )         TRUE if %% <> 0
  5430.  
  5431.        %%0=    ( %% --> flag )         TRUE if %% = 0
  5432.  
  5433.        %%0>    ( %% --> flag )         TRUE if %% > 0
  5434.  
  5435.        %%0>=   ( %% --> flag )         TRUE if %% >= 0
  5436.  
  5437.        %%>     ( %% %%' --> flag )     TRUE if %% > %%'
  5438.  
  5439.        %%>=    ( %% %%' --> flag )     TRUE if %% >= %%'
  5440.  
  5441.        %%<=    ( %% %%' --> flag )     TRUE if %% <= %%'
  5442.  
  5443.  
  5444.        C%%0=   ( C%% --> flag )        TRUE if C%% = (%%0,%%0)
  5445.  
  5446.        C%0=    ( C% --> flag )         TRUE if C% = (0,0)
  5447.  
  5448.  
  5449.        17.2  Words that Operate on the Runstream
  5450.  
  5451.        In many cases, it is desirable to interrupt the normal
  5452.        threaded order of execution, and insert additional objects
  5453.        or skip others in the runstream.  The following words are
  5454.        provided for these purposes.
  5455.  
  5456.        '  ( --> ob )
  5457.  
  5458.          This is the RPL analogue of the Lisp QUOTE and is one of
  5459.          the most fundamental control objects, allowing the
  5460.          evaluation of an object to be postponed. More precisely,
  5461.          assumes that the topmost body in the RUNSTREAM is non-
  5462.          empty, i.e.  the interpreter pointer does not point at a
  5463.          SEMI; and (1) If the next object in the runstream is an
  5464.          object, then pushes this object onto the data stack and
  5465.          moves the interpreter pointer to the next object; (2) If
  5466.          the next object is an object pointer, then pushes the
  5467.          pointee on the data stack and similarly skips to the next
  5468.          object.  As an example, evaluation of the secondaries
  5469.  
  5470.           :: # 3 # 4 SWAP ;      and      :: # 3 # 4 ' SWAP EVAL ;
  5471.  
  5472.          both produce the same result.
  5473.  
  5474.  
  5475.  
  5476.  
  5477.                                  Page 80
  5478.  
  5479.  
  5480.  
  5481.  
  5482.  
  5483.  
  5484.        'R  ( --> ob )
  5485.  
  5486.          If the object pointed to by the top pointer on the return
  5487.          stack (i.e.  the first element in the second body in the
  5488.          runstream) is an object, then 'R pushes this object onto
  5489.          the data stack, and advances the pointer to the next
  5490.          object in the same composite.  If the pointer points to an
  5491.          object pointer whose pointee is not SEMI, then pushes the
  5492.          pointee onto the data stack, and similarly advances the
  5493.          return stack pointer.  If the pointee is SEMI, then If the
  5494.          first element in the second body in the runstream is an
  5495.          object pointer to SEMI, then pushes a null secondary onto
  5496.          the data stack and does not advance the return stack
  5497.          pointer.  'R is useful in defining prefix operators. For
  5498.          example, assume that PREFIXSTO is defined as :: 'R STO ;
  5499.          Then the sequence PREFIXSTO FRED ANOTHEROBJECT would first
  5500.          push FRED onto the data stack and then execute STO, after
  5501.          which execution resumes at ANOTHEROBJECT.
  5502.  
  5503.        ticR  ( --> ob TRUE | FALSE )
  5504.  
  5505.          This word works similarly to 'R, except that it returns a
  5506.          flag to indicate whether the end of the top return stack
  5507.          composite has been reached.  That is, if the top return
  5508.          stack pointer points to an object pointer to SEMI, then
  5509.          ticR pops the return stack and returns only FALSE.
  5510.          Otherwise return the next object from the composite and
  5511.          TRUE, while advancing the return stack pointer to the next
  5512.          object.
  5513.  
  5514.        >R ( :: --> )
  5515.  
  5516.          Inserts the body of :: into the runstream, just below the
  5517.          top one.  (That is, pushes a pointer to the body of ::
  5518.          onto the return stack). An example of its use is
  5519.  
  5520.                          :: ' :: <foo> ; >R <bar> ;
  5521.  
  5522.          which will, when executed, cause <bar> to be executed
  5523.          before <foo>.
  5524.  
  5525.        R>  ( --> :: )
  5526.  
  5527.          Creates a program object from the composite body pointed
  5528.          to by the top return stack pointer, and pushes the program
  5529.          on the data stack and pops the return stack.  Example:
  5530.  
  5531.                        :: :: R> EVAL <foo> ; <bar> ;
  5532.  
  5533.          which, when executed, will cause <bar> to be executed
  5534.          before <foo>.
  5535.  
  5536.        R@ ( --> :: )
  5537.  
  5538.            Same as R> except that the return stack is not popped.
  5539.  
  5540.  
  5541.  
  5542.  
  5543.                                  Page 81
  5544.  
  5545.  
  5546.  
  5547.  
  5548.        RDROP  ( --> )
  5549.  
  5550.          Pops the return stack.
  5551.  
  5552.        IDUP  ( --> )
  5553.  
  5554.          Duplicates the top body in the runstream. (That is, pushes
  5555.          the RPL variable I onto the return stack).
  5556.  
  5557.        COLA  ( --> )
  5558.  
  5559.          Assuming that the interpreter pointer is pointing at an
  5560.          object other than SEMI, COLA drops the remainder of the
  5561.          program body past the object and executes the object.
  5562.          This provides for efficient tail recursion; the efficiency
  5563.          is gained in that COLA can be used to avoid excessive
  5564.          buildup of pending returns. An example of its use is in a
  5565.          definition of factorial:
  5566.  
  5567.                  fact:         :: { LAM x } BIND # 1 factpair ABND
  5568.                                ;
  5569.  
  5570.                  factpair:     :: LAM x #0= ?SEMI
  5571.                                   LAM x #* LAM x #1- ' LAM x
  5572.                                   STO COLA factpair
  5573.                                ;
  5574.  
  5575.          In this example, the importance of COLA is in its
  5576.          occurrence before factpair in the definition of factpair.
  5577.          Without this use, computing n!  would require n return
  5578.          stack levels, which, when the computation was completed,
  5579.          would merely be popped off (since their bodies would be
  5580.          empty).  With the inclusion of COLA, the definition uses a
  5581.          fixed maximum number of levels, independent of the
  5582.          argument to the function.
  5583.  
  5584.        ?SEMI   ( flag --> )
  5585.  
  5586.          Exits the current program if flag is TRUE.
  5587.  
  5588.        ?SEMIDROP  ( ob TRUE --> )  or  ( FALSE --> )
  5589.  
  5590.          Drops ob if flag is TRUE; exits the current program if
  5591.        flag is FALSE.
  5592.  
  5593.        ?SKIP  ( flag --> )
  5594.  
  5595.          If flag is TRUE,  skips the next object following ?SKIP.
  5596.  
  5597.        NOT?SEMI  ( flag --> )
  5598.  
  5599.          Exits the current program if flag is FALSE.
  5600.  
  5601.  
  5602.  
  5603.  
  5604.  
  5605.  
  5606.  
  5607.  
  5608.  
  5609.                                  Page 82
  5610.  
  5611.  
  5612.  
  5613.  
  5614.  
  5615.  
  5616.        17.3  If/Then/Else
  5617.  
  5618.        The fundamental RPL if/then/else capability is provided by
  5619.        means of the words RPIT and RPITE:
  5620.  
  5621.        RPITE   ( flag ob1 ob2 --> ? )
  5622.  
  5623.          If flag is TRUE then drop flag and ob2 and EVALuate ob1,
  5624.          else drop flag and ob1 and EVALuate ob2. The RPL
  5625.          expression
  5626.  
  5627.                            ' <foo> ' <bar> RPITE
  5628.  
  5629.          is equivalent to the FORTH expression
  5630.  
  5631.                           IF <foo> ELSE <bar> THEN
  5632.  
  5633.        RPIT    ( flag ob --> ? )
  5634.  
  5635.          If flag is TRUE then drop flag and EVALuate ob, else just
  5636.          drop flag and ob.  The RPL expression
  5637.  
  5638.                                 ' <foo> RPIT
  5639.  
  5640.          is equivalent to the FORTH expression
  5641.  
  5642.                                IF <foo> THEN
  5643.  
  5644.        However, prefix versions of these words are also available,
  5645.        and are more commonly used than the postfix forms:
  5646.  
  5647.        IT      ( flag -->  )
  5648.  
  5649.          If flag is TRUE then execute the next object in the
  5650.          runstream; otherwise skip that object.  For example,
  5651.  
  5652.                         DUPTYPEREAL? IT :: %0 %>C% ;
  5653.  
  5654.          converts a real number to a complex number; does nothing
  5655.          if the argument is not a real number.
  5656.  
  5657.        ITE     ( flag -->  )
  5658.  
  5659.          If flag is TRUE the execute the next object in the
  5660.          runstream, and skip the second object; otherwise skip the
  5661.          next object and execute the second.  For example,
  5662.  
  5663.                        DUPTYPELIST? ITE INNERCOMP ONE
  5664.  
  5665.          takes a list apart, leaving the count on the stack; for
  5666.          any other type of argument, push a binary integer #1 on
  5667.          the stack.
  5668.  
  5669.  
  5670.  
  5671.  
  5672.  
  5673.  
  5674.  
  5675.                                  Page 83
  5676.  
  5677.  
  5678.  
  5679.  
  5680.  
  5681.  
  5682.        The converse of IT is
  5683.  
  5684.        ?SKIP ( flag --> )
  5685.  
  5686.          If flag is TRUE, skip the next object in the runstream;
  5687.          otherwise, execute it.
  5688.  
  5689.        There is also an unconditional skip:
  5690.  
  5691.        SKIP ( --> )
  5692.  
  5693.          Skips over the next object in the runstream and continues
  5694.          execution beyond it. The sequence SKIP ; is a NOP.
  5695.  
  5696.        Combination Words:
  5697.  
  5698.               Word            Stack          Equivalent
  5699.  
  5700.             #0=ITE      ( # --> )            #0= ITE
  5701.             #<ITE       ( # --> )            #0< ITE
  5702.             #=ITE       ( # --> )            #= ITE
  5703.             #>ITE       ( # --> )            #> ITE
  5704.             ANDITE      ( flag flag' --> )   AND ITE
  5705.             DUP#0=ITE   ( # --> # )          DUP #0= ITE
  5706.             EQIT        ( ob1 ob2 --> )      EQ IT
  5707.             EQITE       ( ob ob' --> )       EQ ITE
  5708.             DUP#0=IT    ( # --> # )          DUP #0= IT
  5709.             SysITE                           ( # --> )
  5710.             UserITE                          ( # --> )
  5711.  
  5712.  
  5713.  
  5714.        17.4  CASE words
  5715.  
  5716.        The word case is a combination of ITE, COLA and SKIP.  That
  5717.        is, case takes a flag from the stack; if TRUE, case executes
  5718.        the object that follows it in the runstream while popping
  5719.        the return stack to the interpreter pointer, discarding the
  5720.        rest of the program that follows the object (like COLA).  If
  5721.        FALSE, case skips the next object and continues with the
  5722.        program (like SKIP). For example, the following program
  5723.        executes different objects according to the value of a
  5724.        binary integer on the stack:
  5725.  
  5726.             :: DUP #0= case ZEROCASE
  5727.                DUP ONE #= case ONECASE
  5728.                DUP TWO #= case TWOCASE
  5729.                ...
  5730.             ;
  5731.  
  5732.  
  5733.  
  5734.  
  5735.  
  5736.  
  5737.  
  5738.  
  5739.  
  5740.  
  5741.                                  Page 84
  5742.  
  5743.  
  5744.  
  5745.  
  5746.  
  5747.  
  5748.        There are several words that contain case as part of their
  5749.        definitions.  The above example can be written more
  5750.        compactly using OVER#=case:
  5751.  
  5752.             :: ZERO OVER#=case ZEROCASE
  5753.                ONE OVER#=case ONECASE
  5754.                TWO OVER#=case TWOCASE
  5755.                ...
  5756.             ;
  5757.  
  5758.        The actions of the words listed below are generally
  5759.        sufficiently clear from their names.  The names have (up to)
  5760.        three parts: an initial part, then "case", then a final
  5761.        part.  The initial part indicates what is done before the
  5762.        case action, i.e. "xxxcase..." is equivalent to "xxx
  5763.        case...".  Words that have a final part after "case" are of
  5764.        two types.  For one type, the final part indicates the
  5765.        conditionally executed object itself, i.e. "...caseyyy" is
  5766.        equivalent to "...case yyy."  In the other type, the final
  5767.        part is a word or words that are incorporated into the
  5768.        following object. caseDROP and casedrop are of the first
  5769.        type and second type, respectively.  caseDROP is equivalent
  5770.        to case DROP; casedrop is like case with a DROP incorporated
  5771.        into the next object.  That is,
  5772.  
  5773.  
  5774.  
  5775.  
  5776.        Words that COLA or SKIP the next object:
  5777.  
  5778.          #=casedrop    ( # # --> )
  5779.                        ( # #' --> # )
  5780.                Should be named OVER#=casedrop.
  5781.  
  5782.          %1=case       ( % --> )
  5783.  
  5784.          %0=case       ( % --> flag )
  5785.  
  5786.          ANDNOTcase    ( flag1 flag2 --> )
  5787.  
  5788.          ANDcase       ( flag1 flag2 --> )
  5789.  
  5790.          case2drop     ( ob1 ob2 TRUE --> )
  5791.                        ( FALSE --> )
  5792.  
  5793.          casedrop      ( ob TRUE --> )
  5794.                        ( FALSE --> )
  5795.  
  5796.          DUP#0=case    ( # --> # )
  5797.  
  5798.          DUP#0=csedrp  ( # --> # ) # <> #0
  5799.                        ( # -->   ) # = #0
  5800.  
  5801.          EQUALNOTcase  ( ob ob' --> )
  5802.  
  5803.          EQUALcase     ( ob ob' --> )
  5804.  
  5805.  
  5806.  
  5807.                                  Page 85
  5808.  
  5809.  
  5810.  
  5811.  
  5812.          EQUALcasedrp  ( ob ob' ob' --> )
  5813.                        ( ob ob' ob'' --> ob )
  5814.  
  5815.          EQcase        ( ob1 ob2 --> )
  5816.  
  5817.          NOTcase       ( flag --> )
  5818.  
  5819.          NOTcasedrop   ( ob FALSE --> )
  5820.                        ( TRUE --> )
  5821.  
  5822.          ORcase        ( flag1 flag2 --> )
  5823.  
  5824.          OVER#=case    ( # #' --> # )
  5825.  
  5826.  
  5827.        Case words that either exit or continue with the next object:
  5828.  
  5829.          caseDoBadKey  ( flag --> ) Exit via DoBadKey
  5830.  
  5831.          caseDrpBadKey ( ob TRUE --> ) Exit via DoBadKey
  5832.                        ( FALSE --> )
  5833.  
  5834.          case2DROP     ( ob1 ob2 TRUE --> )
  5835.                        ( FALSE --> )
  5836.  
  5837.          caseDROP      ( ob TRUE --> )
  5838.                        ( FALSE --> )
  5839.  
  5840.          caseFALSE     ( TRUE --> FALSE )
  5841.                        ( FALSE --> )
  5842.  
  5843.          caseTRUE      ( TRUE --> TRUE )
  5844.                        ( FALSE --> )
  5845.  
  5846.          casedrpfls    ( ob TRUE --> FALSE )
  5847.                        ( FALSE --> )
  5848.  
  5849.          case2drpfls   ( ob1 ob2 TRUE --> FALSE )
  5850.                        ( FALSE --> )
  5851.  
  5852.          casedrptru    ( ob TRUE --> TRUE )
  5853.                        ( FALSE --> )
  5854.  
  5855.          DUP#0=csDROP  ( #0 -->  )
  5856.                        ( #  --> # ) # <> 0.
  5857.          NOTcaseTRUE   ( FALSE --> TRUE )
  5858.                        ( TRUE --> )
  5859.  
  5860.  
  5861.  
  5862.  
  5863.  
  5864.  
  5865.  
  5866.  
  5867.  
  5868.  
  5869.  
  5870.  
  5871.  
  5872.  
  5873.                                  Page 86
  5874.  
  5875.  
  5876.  
  5877.  
  5878.        18.  Stack Operations
  5879.  
  5880.        The words listed in this chapter perform single or multiple
  5881.        stack operations.
  5882.  
  5883.        2DROP           ( ob1 ob2 --> )
  5884.        2DROP00         ( ob1 ob2 --> #0 #0 )
  5885.        2DROPFALSE      ( ob1 ob2 --> FALSE )
  5886.        2DUP            ( ob1 ob2 --> ob1 ob2 ob1 ob2 )
  5887.        2DUP5ROLL       ( ob1 ob2 ob3 --> ob2 ob3 ob2 ob3 ob1 )
  5888.        2DUPSWAP        ( ob1 ob2 --> ob1 ob2 ob2 ob1 )
  5889.        2OVER           ( ob1 ob2 ob3 ob4 --> ob1 ob2 ob3 ob4 ob1 ob2 )
  5890.        2SWAP           ( ob1 ob2 ob3 ob4 --> ob3 ob4 ob1 ob2 )
  5891.        3DROP           ( ob1 ob2 ob3 --> )
  5892.        3PICK           ( ob1 ob2 ob3 --> ob1 ob2 ob3 ob1 )
  5893.        3PICK3PICK      ( ob1 ob2 ob3 --> ob1 ob2 ob3 ob1 ob2 )
  5894.        3PICKOVER       ( ob1 ob2 ob3 --> ob1 ob2 ob3 ob1 ob3 )
  5895.        3PICKSWAP       ( ob1 ob2 ob3 --> ob1 ob2 ob1 ob3 )
  5896.        3UNROLL         ( ob1 ob2 ob3 --> ob3 ob1 ob2 )
  5897.        4DROP           ( ob1 ob2 ob3 ob4 --> )
  5898.        4PICK           ( ob1 ob2 ob3 ob4 --> ob1 ... ob4 ob1 )
  5899.        4PICKOVER       ( ob1 ob2 ob3 ob4 --> ob1 ob2 ob3 ob4 ob1 ob4 )
  5900.        4PICKSWAP       ( ob1 ob2 ob3 ob4 --> ob1 ob2 ob3 ob1 ob4 )
  5901.        4ROLL           ( ob1 ob2 ob3 ob4 --> ob2 ob3 ob4 ob1 )
  5902.        4UNROLL         ( ob1 ob2 ob3 ob4 --> ob4 ob1 ob2 ob3 )
  5903.        4UNROLL3DROP    ( ob1 ob2 ob3 ob4 --> ob4 )
  5904.        4UNROLLDUP      ( ob1 ob2 ob3 ob4 --> ob4 ob1 ob2 ob3 ob3 )
  5905.        4UNROLLROT      ( ob1 ob2 ob3 ob4 --> ob4 ob3 ob2 ob1 )
  5906.        5DROP           ( ob1 ... ob5 --> )
  5907.        5PICK           ( ob1 ... ob5 --> ob1 ... ob5 ob1 )
  5908.        5ROLL           ( ob1 ... ob5 --> ob2 ... ob5 ob1 )
  5909.        5ROLLDROP       ( ob1 ... ob5 --> ob2 ... ob5 )
  5910.        5UNROLL         ( ob1 ... ob5 --> ob5 ob1 ... ob4 )
  5911.        6DROP           ( ob1 ... ob6 --> )
  5912.        6PICK           ( ob1 ... ob6 --> ob1 ... ob6 ob1 )
  5913.        6ROLL           ( ob1 ... ob6 --> ob2 ... ob6 ob1 )
  5914.        7DROP           ( ob1 ... ob7 --> )
  5915.        7PICK           ( ob1 ... ob7 --> ob1 ... ob7 ob1 )
  5916.        7ROLL           ( ob1 ... ob7 --> ob2 ... ob7 ob1 )
  5917.        8PICK           ( ob1 ... ob8 --> ob1 ... ob8 ob1 )
  5918.        8ROLL           ( ob1 ... ob8 --> ob2 ... ob8 ob1 )
  5919.        8UNROLL         ( ob1 ... ob8 --> ob8 ob1 ... ob7 )
  5920.        DEPTH           ( ob1 ... obn ... --> #n )
  5921.        DROP            ( ob --> )
  5922.        DROPDUP         ( ob1 ob2 --> ob1 ob1 )
  5923.        DROPFALSE       ( ob --> FALSE )
  5924.        DROPNDROP       ( ... # ob ) Drops ob, then # objects
  5925.        DROPONE         ( ob --> #1 )
  5926.        DROPOVER        ( ob1 ob2 ob3 --> ob1 ob2 ob1 )
  5927.        DROPRDROP       ( ob --> ) Drops ob, and pops 1 return stk level
  5928.        DROPROT         ( ob1 ob2 ob3 ob4 --> ob2 ob3 ob1 )
  5929.        DROPSWAP        ( ob1 ob2 ob3 --> ob2 ob1 )
  5930.        DROPSWAPDROP    ( ob1 ob2 ob3 --> ob2 )
  5931.        DROPTRUE        ( ob --> TRUE )
  5932.        DROPZERO        ( ob --> #0 )
  5933.        DUP             ( ob --> ob ob )
  5934.        DUP#1+PICK      ( ... #n --> ... #n obn )
  5935.        DUP3PICK        ( ob1 ob2 --> ob1 ob2 ob2 ob1 )
  5936.  
  5937.  
  5938.  
  5939.                                  Page 87
  5940.  
  5941.  
  5942.  
  5943.  
  5944.  
  5945.  
  5946.        DUP4UNROLL      ( ob1 ob2 ob3 --> ob3 ob1 ob2 ob3 )
  5947.        DUPDUP          ( ob --> ob ob ob )
  5948.        DUPONE          ( ob --> ob ob #1 )
  5949.        DUPPICK         ( ... #n --> ... #n obn-1 )
  5950.        DUPROLL         ( ... #n --> ... #n obn-1 )
  5951.        DUPROT          ( ob1 ob2 --> ob2 ob2 ob1 )
  5952.        DUPTWO          ( ob --> ob ob #2 )
  5953.        DUPUNROT        ( ob1 ob2 --> ob2 ob1 ob2 )
  5954.        DUPZERO         ( ob --> ob ob #2 )
  5955.        N+1DROP         ( ob ob1 ... obn #n --> )
  5956.        NDROP           ( ob1 ... obn #n --> )
  5957.        NDUP            ( ob1 ... obn #n --> ob1 ... obn ob1 ... obn )
  5958.        NDUPN           ( ob #n --> ob ... ob )
  5959.        ONEFALSE        ( --> #1 FALSE )
  5960.        ONESWAP         ( ob --> #1 ob )
  5961.        OVER            ( ob1 ob2 --> ob1 ob2 ob1 )
  5962.        OVER5PICK       ( v w x y z --> v w x y z y v )
  5963.        OVERDUP         ( ob1 ob2 --> ob1 ob2 ob1 ob1 )
  5964.        OVERSWAP        ( ob1 ob2 --> ob2 ob1 ob1 )
  5965.        OVERUNROT       ( ob1 ob2 --> ob1 ob1 ob2 )
  5966.        PICK            ( obn ... #n --> ... obn )
  5967.        ROLL            ( obn ... #n --> ... obn )
  5968.        ROLLDROP        ( obn ... #n --> ... )
  5969.        ROLLSWAP        ( obn ... ob #n --> ... obn ob )
  5970.        ROT             ( ob1 ob2 ob3 --> ob2 ob3 ob1 )
  5971.        ROT2DROP        ( ob1 ob2 ob3 --> ob2 )
  5972.        ROT2DUP         ( ob1 ob2 ob3 --> ob2 ob3 ob1 ob3 ob1 )
  5973.        ROTDROP         ( ob1 ob2 ob3 --> ob2 ob3 )
  5974.        ROTDROPSWAP     ( ob1 ob2 ob3 --> ob3 ob2 )
  5975.        ROTDUP          ( ob1 ob2 ob3 --> ob2 ob3 ob1 ob1 )
  5976.        ROTOVER         ( ob1 ob2 ob3 --> ob2 ob3 ob1 ob3 )
  5977.        ROTROT2DROP     ( ob1 ob2 ob3 --> ob3 )
  5978.        ROTSWAP         ( ob1 ob2 ob3 --> ob2 ob1 ob3 )
  5979.        SWAP            ( ob1 ob2 --> ob2 ob1 )
  5980.        SWAP2DUP        ( ob1 ob2 --> ob2 ob1 ob2 ob1 )
  5981.        SWAP3PICK       ( ob1 ob2 ob3 --> ob1 ob3 ob2 ob1 )
  5982.        SWAP4PICK       ( ob1 ob2 ob3 ob4 --> ob1 ob2 ob4 ob3 ob4 )
  5983.        SWAPDROP        ( ob1 ob2 --> ob2 )
  5984.        SWAPDROPDUP     ( ob1 ob2 --> ob2 ob2 )
  5985.        SWAPDROPSWAP    ( ob1 ob2 ob3 --> ob3 ob1 )
  5986.        SWAPDROPTRUE    ( ob1 ob2 --> ob2 TRUE )
  5987.        SWAPDUP         ( ob1 ob2 --> ob2 ob1 ob1 )
  5988.        SWAPONE         ( ob1 ob2 --> ob2 ob1 #1 )
  5989.        SWAPOVER        ( ob1 ob2 --> ob2 ob1 ob2 )
  5990.        SWAPROT         ( ob1 ob2 ob3 --> ob3 ob2 ob1 )
  5991.        SWAPTRUE        ( ob1 ob2 --> ob2 ob1 TRUE )
  5992.        UNROLL          ( ... ob #n --> ob ... )
  5993.        UNROT           ( ob1 ob2 ob3 --> ob3 ob1 ob2 )
  5994.        UNROT2DROP      ( ob1 ob2 ob3 --> ob3 )
  5995.        UNROTDROP       ( ob1 ob2 ob3 --> ob3 ob1 )
  5996.        UNROTDUP        ( ob1 ob2 ob3 --> ob3 ob1 ob2 ob2 )
  5997.        UNROTOVER       ( ob1 ob2 ob3 --> ob3 ob1 ob2 ob1 )
  5998.        UNROTSWAP       ( ob1 ob2 ob3 --> ob3 ob2 ob1 )
  5999.        ZEROOVER        ( ob --> ob #0 ob )
  6000.        reversym        ( ob1 ... obn #n --> obn ... ob1 #n )
  6001.  
  6002.  
  6003.  
  6004.  
  6005.                                  Page 88
  6006.  
  6007.  
  6008.  
  6009.  
  6010.        19.  Memory Operations
  6011.  
  6012.        The words presented in this chapter manipulate directories,
  6013.        variables, and system ram.
  6014.  
  6015.  
  6016.        19.1  Temporary Memory
  6017.  
  6018.        The user word NEWOB creates a new copy of an object in
  6019.        temporary memory.  There are a few internal variations on
  6020.        this theme:
  6021.  
  6022.        CKREF           ( ob --> ob' )
  6023.                          If ob is in TEMPOB, is not embedded
  6024.                          in a composite object, and is not
  6025.                          referenced, then does nothing. Otherwise
  6026.                          copies ob to TEMPOB and returns the copy.
  6027.  
  6028.        INTEMNOTREF?    ( ob --> ob flag )
  6029.                          If the input object is in TEMPOB area,
  6030.                          is not embedded in a composite object,
  6031.                          and is not referenced, returns ob and
  6032.                          TRUE, otherwise returns ob and FALSE.
  6033.  
  6034.        TOTEMPOB        ( ob --> ob' )
  6035.                          Copies ob into TEMPOB and returns pointer
  6036.                          to the new ob.
  6037.  
  6038.  
  6039.        19.2  Variables and Directories
  6040.  
  6041.        The system RPL basis of user STO and RCL is the words STO,
  6042.        CREATE, and @:
  6043.  
  6044.        CREATE ( ob id --> )
  6045.          Creates a RAM-WORD with ob as its object part and the NAME
  6046.          FORM from id as its name part, in the current directory.
  6047.          An error occurs if ob is or contains the current directory
  6048.          ("Directory Recursion"). Assumes that ob is not a
  6049.          primitive code object.
  6050.  
  6051.        STO ( ob id --> )
  6052.            ( ob lam --> )
  6053.          In the lam case, the temporary identifier lam is re-bound
  6054.          to ob.  The binding is to the first such temporary
  6055.          identifier object matching lam in the Temporary
  6056.          Environment area (searching from the first temporary
  6057.          environment to the last). An error is returned if lam is
  6058.          unbound.  In the id case, STO attempts to match id to the
  6059.          name part of a global variable.  If resolution is
  6060.          unsuccessful, STO creates a variable with ob as its object
  6061.          part and the name form from id as its name part, in the
  6062.          current directory. If resolution is successful, then ob
  6063.          replaces the object part of the resolved variable. If any
  6064.          updatable system object pointers reference the object part
  6065.          of the resolved variable, then the object part is placed
  6066.          into the temporary object area prior to the replacement
  6067.          and all affected updatable system object pointers are
  6068.  
  6069.  
  6070.  
  6071.                                  Page 89
  6072.  
  6073.  
  6074.  
  6075.  
  6076.  
  6077.  
  6078.          adjusted to reference the copy of the object part in the
  6079.          temporary object area.  For the id case, STO assumes that
  6080.          ob is not a primitive code object.
  6081.  
  6082.        @   ( id --> ob TRUE )
  6083.            ( id --> FALSE )
  6084.            ( lam --> ob TRUE )
  6085.            ( lam --> FALSE )
  6086.          In the lam case, @ attempts to match lam to the temporary
  6087.          identifier object part of a binding in the Temporary
  6088.          Environment area (searching from the first temporary
  6089.          environment to the last). If successful, then the object
  6090.          bound to lam is returned along with a TRUE flag; else, a
  6091.          FALSE flag is returned.  In the id case, @ attempts to
  6092.          match id to the name part of a global variable, starting
  6093.          in the current directory, and working up through parent
  6094.          directories if necessary.  If the resolution is
  6095.          unsuccessful, then a FALSE flag is returned. Otherwise,
  6096.          the object part of the resolved variable is returned with
  6097.          a TRUE flag.
  6098.  
  6099.        One difficulty in using STO and @ is that they make no
  6100.        distinctions for built-in commands; with SIN as its (object)
  6101.        argument, STO will blithely copy the entire body of SIN into
  6102.        a variable.  @ then would recall that undecompilable
  6103.        program.  For this reason, it is better to use SAFESTO and
  6104.        SAFE@, which work like STO and @ except that they
  6105.        automatically convert ROM bodies into XLIB names (SAFESTO)
  6106.        and back again (SAFE@).
  6107.  
  6108.        Additional extensions are:
  6109.  
  6110.        ?STO_HERE ( ob id --> )
  6111.                  ( ob lam --> )
  6112.          This is the system version of user STO.  It is the same as
  6113.          SAFESTO, except that for global variables, it a) stores
  6114.          only in the current directory; and b) will not overwrite a
  6115.          stored directory.
  6116.  
  6117.        SAFE@_HERE ( id --> ob TRUE )
  6118.                   ( id --> FALSE )
  6119.                   ( lam --> ob TRUE )
  6120.                   ( lam --> FALSE )
  6121.        Same as SAFE@, except for global variables the search is restricted to the
  6122.        current directory.
  6123.  
  6124.          Other related words:
  6125.  
  6126.          PURGE   ( id --> ) Purges variable specified by id; does
  6127.          no type check on
  6128.                             stored object.
  6129.  
  6130.          XEQRCL  ( id  --> ob ) Same as SAFE@ for global variables,
  6131.          but errors
  6132.                             if variable is nonexistent
  6133.  
  6134.  
  6135.  
  6136.  
  6137.                                  Page 90
  6138.  
  6139.  
  6140.  
  6141.  
  6142.          XEQSTOID ( ob id --> ) Alternate name for ?STO_HERE
  6143.  
  6144.  
  6145.        19.2.1  Directories  A directory (abbreviated "rrp" from its
  6146.        original name "ramrompair") is an object whose body contains
  6147.        a linked-list of global variables--named objects referenced
  6148.        by global names.  The body also contains a library ID number
  6149.        that associates ("attaches") a library object with the
  6150.        directory so that the library's commands follow the
  6151.        directory's variables in the name compilation search order.
  6152.  
  6153.        A directory may be "rooted", i.e. stored in a global
  6154.        variable (which may be within another directory body), in
  6155.        which case its variable's names are available for
  6156.        compilation.  The particular directory in which a name
  6157.        resolution search begins is called the "current directory,"
  6158.        or the "context directory;" this directory is specified by
  6159.        the contents of a system RAM location.  An unrooted
  6160.        directory (in tempob or in a port, for example), should
  6161.        never be selected as the context directory.  Nor can there
  6162.        be any references within a directory in tempob; a directory
  6163.        is not a composite object, so garbage collection cannot work
  6164.        properly if such references exist.  For this reason, an
  6165.        internally referenced directory should not be removed by
  6166.        PURGE--use XEQPGDIR instead.
  6167.  
  6168.        In addition to the context, another system RAM location
  6169.        identifies the "stopsign" directory, which is acts as the
  6170.        ending point for a name resolution search much as the
  6171.        context directory is the starting point.  By using the
  6172.        stopsign, you can restrict name resolution searches to a
  6173.        specific range; however, you should use error traps to
  6174.        insure that the stopsign is reset to the home directory when
  6175.        an error occurs.
  6176.  
  6177.        The home directory (aka "sysramrompair") is the default for
  6178.        both context and stopsign.  This is not a normal directory,
  6179.        in that it is never unrooted, and contains additional
  6180.        structure that ordinary directories don't have (such as
  6181.        multiple library attachments and alternate message and
  6182.        command hash tables).
  6183.  
  6184.        A directory is a data-class object so that execution of a
  6185.        directory merely returns it to the stack.  However, global
  6186.        name execution has the property that executing the name of a
  6187.        rooted (stored) directory makes that directory the current
  6188.        directory rather than executing the directory itself.
  6189.  
  6190.        The following words are available for directory
  6191.        manipulation:
  6192.        CONTEXT! ( rrp --> )
  6193.          Stores a pointer to a rooted directory as the current directory
  6194.  
  6195.        CONTEXT@ ( --> rrp )
  6196.          Recalls the current context directory.
  6197.  
  6198.        CREATEDIR       ( id --> )
  6199.          Creates a directory object in the current directory.
  6200.  
  6201.  
  6202.  
  6203.                                  Page 91
  6204.  
  6205.  
  6206.  
  6207.  
  6208.  
  6209.  
  6210.        DOVARS  ( --> { id1 id2 ... } )
  6211.          Returns list of variable names from the current directory.
  6212.  
  6213.        HOMEDIR ( --> )
  6214.          Makes HOME the current directory.
  6215.  
  6216.        PATHDIR ( --> { HOME dir dir ... } )
  6217.          Returns the current path.
  6218.  
  6219.        UPDIR   ( --> )
  6220.          Switches context to the parent of the current directory.
  6221.  
  6222.        XEQORDER ( { id1 id2 ... } --> )
  6223.          ORDERs current directory.
  6224.  
  6225.        XEQPGDIR ( id --> )
  6226.          Purges a directory while respecting reference/garbage collection conventions.
  6227.  
  6228.  
  6229.        19.3  The Hidden Directory
  6230.  
  6231.        There is a hidden, nullnamed directory at the beginning of
  6232.        the home directory, that contains the user key definitions
  6233.        and alarm information.  Application programs may use this
  6234.        directory as well.  However, remember that the user has no
  6235.        way to detect or remove variables from this directory, so an
  6236.        application should either remove such variables before
  6237.        finishing, or to provide a command that lets the user remove
  6238.        specific variables from the hidden directory.
  6239.  
  6240.        These words provide store, recall and purge capabilities for
  6241.        the hidden directory:
  6242.  
  6243.        PuHiddenVar  ( id --> )  Purges the hidden variable named id.
  6244.  
  6245.        RclHiddenVar ( id --> ob TRUE )
  6246.                     ( id --> FALSE   )
  6247.          Recalls (@) a hidden variable.
  6248.  
  6249.        StoHiddenVar    ( ob id --> )
  6250.          Stores ob in hidden variable
  6251.  
  6252.  
  6253.  
  6254.  
  6255.  
  6256.  
  6257.  
  6258.  
  6259.  
  6260.  
  6261.  
  6262.  
  6263.  
  6264.  
  6265.  
  6266.  
  6267.  
  6268.  
  6269.                                  Page 92
  6270.  
  6271.  
  6272.  
  6273.  
  6274.  
  6275.  
  6276.        19.4  Additional Memory Utilities
  6277.  
  6278.        GARBAGE  ( --> )
  6279.          Forces garbage collection.
  6280.  
  6281.        MEM( --> # )
  6282.          Returns the amount of free memory (a garbage collection is not forced)
  6283.  
  6284.        OCRC ( ob --> #nibbles checksum(hxs)  Returns size of object in nibbles and
  6285.          a hex string checksum
  6286.  
  6287.        getnibs ( hxsDATA hxsADDR --> hxsDATA' ) Internal RPL version of PEEK
  6288.  
  6289.        putnibs ( hxsDATA hxsADDR --> ) Internal RPL version of POKE
  6290.  
  6291.  
  6292.  
  6293.  
  6294.  
  6295.  
  6296.  
  6297.  
  6298.  
  6299.  
  6300.  
  6301.  
  6302.  
  6303.  
  6304.  
  6305.  
  6306.  
  6307.  
  6308.  
  6309.  
  6310.  
  6311.  
  6312.  
  6313.  
  6314.  
  6315.  
  6316.  
  6317.  
  6318.  
  6319.  
  6320.  
  6321.  
  6322.  
  6323.  
  6324.  
  6325.  
  6326.  
  6327.  
  6328.  
  6329.  
  6330.  
  6331.  
  6332.  
  6333.  
  6334.  
  6335.                                  Page 93
  6336.  
  6337.  
  6338.  
  6339.  
  6340.  
  6341.  
  6342.        20.  Display Management & Graphics
  6343.  
  6344.        Most user RPL graphics commands are directed to the graphics
  6345.        screen, which is the graphics object visible in the plot
  6346.        environment. However, the "text screen," the grob visible in
  6347.        the standard stack environment, has the same properties as
  6348.        the graph screen, and should be used by application programs
  6349.        for graphics displays whenever possible, to leave the graph
  6350.        screen as a user "owned" resource. The EquationWriter does
  6351.        this, for example, as does the HP82211A HP Solve Equation
  6352.        Library card.
  6353.  
  6354.  
  6355.        20.1  Display Organization
  6356.  
  6357.        HP 48 system RAM contains three dedicated graphics objects
  6358.        used for display purposes:
  6359.  
  6360.           Pointer           Grob        Location
  6361.          ---------    ----------------  ---------
  6362.  
  6363.                       +--------------+
  6364.          HARDBUFF2 -> | Menu labels  |  (Low Mem)
  6365.                       +--------------+
  6366.          ABUFF     -> | text  grob   |
  6367.                       +--------------+
  6368.          GBUFF     -> | graph grob   |  (Hi  Mem)
  6369.                       +--------------+
  6370.  
  6371.        The text grob and graph grob may be enlarged, and may be
  6372.        scrolled.
  6373.  
  6374.        The word TOADISP switches makes the text grob visible;
  6375.        TOGDISP switches the LCD to the graph grob.
  6376.  
  6377.        The following words are useful for returning display grobs
  6378.        to the stack:
  6379.  
  6380.        ABUFF  ( --> textgrob )
  6381.        GBUFF  ( --> graphgrob )
  6382.        HARDBUFF  ( --> HBgrob )
  6383.          Returns whichever of the text or graph grob is currently displayed.
  6384.        HARDBUFF2 ( --> menugrob )
  6385.        HBUFF_X_Y( --> HBgrob #x1 #y1 )
  6386.  
  6387.        A ram pointer named VDISP indicates which grob is currently
  6388.        shown in the display.  VDISP may point to either the text
  6389.        grob or the graph grob.  VDISP is not directly accessible -
  6390.        the word HARDBUFF returns the current display grob to the
  6391.        stack (see below).  Remember that ABUFF and GBUFF just
  6392.        return pointers, so if the grob is being recalled for
  6393.        modification and later return to the user, TOTEMPOB should
  6394.        be used to create a unique copy in temporary memory.
  6395.  
  6396.  
  6397.  
  6398.  
  6399.  
  6400.  
  6401.                                  Page 94
  6402.  
  6403.  
  6404.  
  6405.  
  6406.  
  6407.  
  6408.        From a user's point of view, the text display is organized
  6409.        into three regions, and the internal numbering convention
  6410.        for these areas is reflected in many of the display control
  6411.        words (see "Display Area Control" below).  The display areas
  6412.        are numbered 1, 2, and 3.  The letters "DA", for "Display
  6413.        Area", are found in the names of some display control words.
  6414.  
  6415.                  +-------------------+
  6416.             DA1  | directory    time | Status line (16 lines)
  6417.                  +-------------------+
  6418.                  |4:                 |
  6419.             DA2a |3:                 | Stack
  6420.                  +-------------------+ Display
  6421.             DA2b |2:                 | (40 lines total)
  6422.                  |1:                 |
  6423.                  +-------------------+
  6424.             DA3  | 1  2  3   4  5  6 | Menu labels (8 lines)
  6425.                  +-------------------+
  6426.  
  6427.        Display area 2 is actually divided into areas 2a and 2b, a
  6428.        distinction most often used by the command line line.  The
  6429.        boundary between 2a and 2b can move, but the overall sizes
  6430.        of areas 1, 2, and 3 are fixed.
  6431.  
  6432.  
  6433.        20.2  Preparing the Display
  6434.  
  6435.        Two words establish control over the text display.  These
  6436.        words are RECLAIMDISP and ClrDA1IsStat.
  6437.  
  6438.        The word RECLAIMDISP performs the following actions:
  6439.  
  6440.           + Makes sure the text grob is the current display.
  6441.  
  6442.           + Clears the text display.
  6443.  
  6444.           + Resizes the text grob to the standard size (131 wide by
  6445.             56 high) if necessary.
  6446.  
  6447.        RECLAIMDISP is very much like the user word CLLCD, except
  6448.        that CLLCD does not resize the text grob.
  6449.  
  6450.        The word ClrDA1IsStat suspends the ticking clock display,
  6451.        and is optional. If user input will be requested using words
  6452.        like WaitForKey or a parameterized outer loop (see "Keyboard
  6453.        Input"), then the clock updates will continue, and may botch
  6454.        the display.
  6455.  
  6456.        An example usage of ClrDA1IsStat can be found in the
  6457.        Periodic Table application, where a user can enter a
  6458.        molecular formula.  The word WaitForKey is used to get
  6459.        keystrokes, and ClrDA1IsStat prevents the clock from
  6460.        overwriting the Periodic Table grid display.
  6461.  
  6462.        If the menu display is not needed, the word TURNMENUOFF will
  6463.        remove DA3 from the display and enlarge the text grob to be
  6464.  
  6465.  
  6466.  
  6467.                                  Page 95
  6468.  
  6469.  
  6470.  
  6471.  
  6472.  
  6473.  
  6474.        131x64. The corresponding word TURNMENUON restores the menu
  6475.        display.
  6476.  
  6477.        A simplified framework for an application secondary which
  6478.        can be invoked by an end user and uses the text display
  6479.        looks like this:
  6480.  
  6481.        ::
  6482.          ClrDA1IsStat          ( *Suspend clock display updates* )
  6483.          RECLAIMDISP           ( *Assert & clear alpha display* )
  6484.          TURNMENUOFF           ( *Remove menu keys* )
  6485.  
  6486.          < application >
  6487.  
  6488.          ClrDAsOK   -\         ( *Tell the 48 to redraw the lcd* )
  6489.            -or-       > Choose one
  6490.          SetDAsTemp -/         ( *Freeze all display areas* )
  6491.        ;
  6492.  
  6493.  
  6494.  
  6495.        20.3  Controlling Display Refresh
  6496.  
  6497.        When an application terminates or returns to the system
  6498.        outer loop for keyboard input, several internal versions of
  6499.        the user word FREEZE are available to control the display,
  6500.        and there is a word that ensures that certain display or all
  6501.        display areas will be redrawn:
  6502.  
  6503.        SetDA1Temp      Freeze display area 1
  6504.        SetDA2aTemp     Freeze display area 2a
  6505.        SetDA2bTemp     Freeze display area 2b
  6506.        SetDA3Temp      Freeze display area 3
  6507.        SetDAsTemp      Freeze all display areas
  6508.        ClrDAsOK        Redraw the entire lcd when program ends
  6509.  
  6510.        There are still more variations on this theme - see the
  6511.        chapter "Keyboard Input" for more.
  6512.  
  6513.  
  6514.  
  6515.  
  6516.  
  6517.  
  6518.  
  6519.  
  6520.  
  6521.  
  6522.  
  6523.  
  6524.  
  6525.  
  6526.  
  6527.  
  6528.  
  6529.  
  6530.  
  6531.  
  6532.  
  6533.                                  Page 96
  6534.  
  6535.  
  6536.  
  6537.  
  6538.  
  6539.  
  6540.        20.4  Clearing the Display
  6541.  
  6542.        The following words may be used to clear either the whole
  6543.        display or a portion of HARDBUFF. Remember that HARDBUFF
  6544.        refers to the currently displayed grob, which is either the
  6545.        text grob or the graph grob.
  6546.  
  6547.        BLANKIT         ( #startrow #rows --> )
  6548.                          Clears #rows starting at #startrow
  6549.        BlankDA12       ( --> )
  6550.                          Clears rows 0 through 56
  6551.        BlankDA2        ( --> )
  6552.                          Clears rows 16 through 56
  6553.        CLEARVDISP      ( --> )
  6554.                          Zeros out all of HARDBUFF
  6555.        Clr16           ( --> )
  6556.                          Clears top 16 pixel rows
  6557.        Clr8            ( --> )
  6558.                          Clears top 8 pixel rows
  6559.        Clr8-15         ( --> )
  6560.                          Clears pixel rows 8-15
  6561.  
  6562.  
  6563.        20.5  Annunciator Control
  6564.  
  6565.        The following words control the left-shift, right-shift, and
  6566.        alpha annunciators.  It is unlikely that an application
  6567.        should have to control these directly, and misuse of these
  6568.        words can lead to misleading displays after an application
  6569.        terminates.
  6570.  
  6571.        ClrAlphaAnn     Clears the alpha annunciator
  6572.        ClrLeftAnn      Clears the left-shift annunciator
  6573.        ClrRightAnn     Clears the right-shift annunciator
  6574.        SetAlphaAnn     Sets the alpha annunciator
  6575.        SetLeftAnn      Sets the left-shift annunciator
  6576.        SetRightAnn     Sets the right-shift annunciator
  6577.  
  6578.  
  6579.  
  6580.  
  6581.  
  6582.  
  6583.  
  6584.  
  6585.  
  6586.  
  6587.  
  6588.  
  6589.  
  6590.  
  6591.  
  6592.  
  6593.  
  6594.  
  6595.  
  6596.  
  6597.  
  6598.  
  6599.                                  Page 97
  6600.  
  6601.  
  6602.  
  6603.  
  6604.  
  6605.  
  6606.        20.6  Display Coordinates
  6607.  
  6608.        The upper-left pixel of the display has the coordinates x=0
  6609.        y=0, which are the same as user pixel coordinates { #0 #0 }.
  6610.        The lower-right pixel coordinate is x=130 y=63.
  6611.  
  6612.        NOTE: subgrobs are taken from the upper-left coordinate to
  6613.        the pixel below and to the right of the lower right corner.
  6614.        The terms #x1 and #y1 refer to the upperleft pixel of a sub
  6615.        area, while #x2 and #y2 refer to the pixel below and the
  6616.        right of the lower right corner.
  6617.  
  6618.  
  6619.         { #0 #0 } +------------------------------+
  6620.         {#x1 #y1} |*                             |
  6621.                   |                              |
  6622.                   |       GOR +----+             |
  6623.                   | coordinate|*   |             |
  6624.                   |           |    |             |
  6625.                   |           +----+             |
  6626.                   |                 * Subgrob    |
  6627.                   |                   coordinate |
  6628.                   |                              |
  6629.                   |                             *|  <- { #130 #63 }
  6630.                   +------------------------------+
  6631.                                                   * <- { #x2  #y2 }
  6632.  
  6633.  
  6634.  
  6635.        20.6.1  Window_Coordinates
  6636.  
  6637.        The following routines return HARDBUFF and coordinates for
  6638.        portions of the display in a form suitable for a subsequent
  6639.        call to SUBGROB. The terms #x1 and #y1 refer to the upper
  6640.        left corner of the window on the currently displayed grob.
  6641.        If the grob has been scrolled, these will NOT be #0 #0!
  6642.  
  6643.        If HARDBUFF has been scrolled, some display words may not be
  6644.        appropriate to use since they depend on the upper left
  6645.        corner of the display being #0 #0.  The LCD is then called
  6646.        the "window", and the terms #x1 and #y1 will refer to the
  6647.        pixel coordinates of the upper left corner of the window.
  6648.        The word HBUFF_X_Y returns HARDBUFF and these window
  6649.        coordinates.  The word WINDOWCORNER returns just the window
  6650.        coordinates.  The words DISPROW1* and DISPROW2* mentioned
  6651.        below work relative to the window corner.
  6652.  
  6653.        Rows8-15        ( --> HBgrob #x1 #y1+8 #x1+131 #y1+16 )
  6654.        TOP16           ( --> HBgrob #x1 #y1 #x1+131 #y1+16 )
  6655.        TOP8            ( --> HBgrob #x1 #y1 #x1+131 #y1+8 )
  6656.        WINDOWCORNER    ( --> #x #y )
  6657.                          Returns pixel numbers of upperleft corner
  6658.                          of the window
  6659.  
  6660.  
  6661.  
  6662.  
  6663.  
  6664.  
  6665.                                  Page 98
  6666.  
  6667.  
  6668.  
  6669.  
  6670.  
  6671.  
  6672.        The word Save16 calls TOP16 and SUBGROB to produce a grob
  6673.        consisting of the top 16 rows of the current display:
  6674.  
  6675.        Save16          ( --> grob )
  6676.  
  6677.        Equivalent words that save the top eight rows or rows 8-15
  6678.        are not in the HP 48, but can be written as follows:
  6679.  
  6680.        :: TOP8 SUBGROB ; ( --> grob ) ( *Saves the top 8 rows* )
  6681.        :: TOP8-15 SUBGROB ; ( --> grob ) ( *Saves the top 8-15 rows* )
  6682.  
  6683.  
  6684.        20.7  Displaying Text
  6685.  
  6686.        There are three fonts available in the HP 48, distinguished
  6687.        by size.  The smallest font is variable width; the medium
  6688.        and large fonts are fixed width.
  6689.  
  6690.        The words described below display text using the medium and
  6691.        large fonts in specific areas.  Use of the small fonts, and
  6692.        other placement options for the medium and large fonts must
  6693.        be done in graphics, which is described later.
  6694.  
  6695.  
  6696.        20.7.1  Standard_Text_Display_Areas
  6697.  
  6698.        When the text grob is the current display AND has not been
  6699.        scrolled, the following words may be used to display text in
  6700.        the medium (5x7) font.  Long strings are truncated to 22
  6701.        characters with a trailing ellipsis (...), and strings
  6702.        shorter than 22 characters are blank filled.
  6703.  
  6704.        DISPROW1        ( $ --> )
  6705.        DISPROW2        ( $ --> )
  6706.        DISPROW3        ( $ --> )
  6707.        DISPROW4        ( $ --> )
  6708.        DISPROW5        ( $ --> )
  6709.        DISPROW6        ( $ --> )
  6710.        DISPROW7        ( $ --> )
  6711.        DISPN           ( $ #row --> )
  6712.        DISP5x7         ( $ #start #max )
  6713.  
  6714.  
  6715.                                (0,0)                (130,0)
  6716.           DISPROW1 writes into   +--------------------+
  6717.                                  |                    |
  6718.                                  +--------------------+
  6719.                                (0,7)                 (130,7)
  6720.  
  6721.                                (0,8)                 (130,8)
  6722.           DISPROW2 writes into   +--------------------+
  6723.                                  |                    |
  6724.                                  +--------------------+
  6725.                                (0,15)                (130,15)
  6726.                 (etc.)
  6727.  
  6728.  
  6729.  
  6730.  
  6731.                                  Page 99
  6732.  
  6733.  
  6734.  
  6735.  
  6736.  
  6737.  
  6738.        The word DISP5x7 may be used to display a string that spans
  6739.        more than one line of the display. The string must have
  6740.        embedded carriage returns to show where to break to the next
  6741.        display line.  If a line segment is greater than 22
  6742.        characters, it will be truncated and displayed with a
  6743.        trailing ellipsis (...).  The string is displayed starting
  6744.        at row #start for #max rows.
  6745.  
  6746.        The following words may be used to display text in the large
  6747.        (5x9) font.  Long strings are truncated to 22 characters
  6748.        with a trailing ellipsis (...), and strings shorter than 22
  6749.        characters are blank filled.
  6750.  
  6751.        BIGDISPROW1     ( $ --> )
  6752.        BIGDISPROW2     ( $ --> )
  6753.        BIGDISPROW3     ( $ --> )
  6754.        BIGDISPROW4     ( $ --> )
  6755.        BIGDISPN        ( $ #row --> )
  6756.  
  6757.  
  6758.                                (0,17)              (130,0)
  6759.        BIGDISPROW1 writes into   +--------------------+
  6760.                                  |                    |
  6761.                                  +--------------------+
  6762.                                (0,26)              (130,26)
  6763.  
  6764.                                (0,27)              (130,27)
  6765.        BIGDISPROW2 writes into   +--------------------+
  6766.                                  |                    |
  6767.                                  +--------------------+
  6768.                                (0,36)              (130,36)
  6769.                 (etc.)
  6770.  
  6771.  
  6772.  
  6773.  
  6774.  
  6775.  
  6776.  
  6777.  
  6778.  
  6779.  
  6780.  
  6781.  
  6782.  
  6783.  
  6784.  
  6785.  
  6786.  
  6787.  
  6788.  
  6789.  
  6790.  
  6791.  
  6792.  
  6793.  
  6794.  
  6795.  
  6796.  
  6797.                                  Page 100
  6798.  
  6799.  
  6800.  
  6801.  
  6802.        20.7.2  Temporary_Messages
  6803.  
  6804.        Sometimes it is convenient to display a warning, then return
  6805.        the display to its previous state.  There are several
  6806.        techniques and tools available for this.  The easiest way to
  6807.        do this is with the word FlashWarning. The code for
  6808.        FlashWarning looks like this:
  6809.  
  6810.        FlashWarning            ( $ --> )
  6811.        ::
  6812.          ERRBEEP               ( *Generate an error beep* )
  6813.          Save16                ( *Save the top 16 pixel rows* )
  6814.          SWAP DISPSTATUS2      ( *Display the warning* )
  6815.          VERYVERYSLOW          ( *Wait about 3 seconds* )
  6816.          Restore16             ( *Restore the top 16 rows* )
  6817.        ;
  6818.  
  6819.        Variations on FlashWarning can be constructed using words
  6820.        like TOP16 or a version suggested above that saves fewer
  6821.        rows.  The example below saves the top 8 rows and displays a
  6822.        one line message for about .6 second:
  6823.  
  6824.        ::
  6825.          TOP8 SUBGROB          ( *Save the top 8 rows* )
  6826.          SWAP DISPROW1*        ( *Display the message* )
  6827.          VERYSLOW VERYSLOW     ( *Short delay* )
  6828.          Restore8              ( *Restore the top 8 rows* )
  6829.        ;
  6830.  
  6831.        NOTE: It is important to use DISPROW1* and DISPROW2* instead
  6832.        of DISPROW1 and DISPROW2 if there is any chance that
  6833.        HARDBUFF has been scrolled.  There are no corresponding
  6834.        words for other display lines.
  6835.  
  6836.  
  6837.  
  6838.  
  6839.  
  6840.  
  6841.  
  6842.  
  6843.  
  6844.  
  6845.  
  6846.  
  6847.  
  6848.  
  6849.  
  6850.  
  6851.  
  6852.  
  6853.  
  6854.  
  6855.  
  6856.  
  6857.  
  6858.  
  6859.  
  6860.  
  6861.  
  6862.  
  6863.                                  Page 101
  6864.  
  6865.  
  6866.  
  6867.  
  6868.  
  6869.  
  6870.        20.8  Graphics Objects
  6871.  
  6872.        The following section presents tools for creating,
  6873.        manipulating, and displaying graphics objects.
  6874.  
  6875.  
  6876.        20.8.1  Warnings
  6877.  
  6878.        Here are two warnings:
  6879.  
  6880.          1.  The term "bang-type operation" refers to an operation
  6881.              performed directly upon an object without making a
  6882.              copy.  The naming convention for words which perform
  6883.              this kind of operation often have an exclamation point
  6884.              to denote a "bang" operation, such as GROB! or
  6885.              GROB!ZERO.
  6886.  
  6887.              You must remember two things when using "bang"
  6888.              operations:
  6889.  
  6890.               + Since the object itself is modified, any pointers
  6891.                 on the stack that refer to that object will now
  6892.                 point to a changed object.  The word CKREF may be
  6893.                 used to ensure that an object is unique.
  6894.  
  6895.               + These operations have no error checking, so
  6896.                 improper or out-of-range parameters may corrupt
  6897.                 memory beyond recovery.
  6898.  
  6899.          2.  In practice, it is best to use the word XYGROBDISP to
  6900.              place a grob into the display grob.  The word
  6901.              XYGROBDISP is conservative in nature - if the graphic
  6902.              to be placed in HARDBUFF would exceed the boundaries
  6903.              of HARDBUFF, the HARDBUFF grob is enlarged to
  6904.              accomodate the new grob.
  6905.  
  6906.  
  6907.  
  6908.  
  6909.  
  6910.  
  6911.  
  6912.  
  6913.  
  6914.  
  6915.  
  6916.  
  6917.  
  6918.  
  6919.  
  6920.  
  6921.  
  6922.  
  6923.  
  6924.  
  6925.  
  6926.  
  6927.  
  6928.  
  6929.                                  Page 102
  6930.  
  6931.  
  6932.  
  6933.  
  6934.  
  6935.  
  6936.        20.8.2  Graphics_Tools
  6937.  
  6938.        The following words create or modify graphics objects:
  6939.        $>BIGGROB       ( $ --> grob ) ( 5x9 font )
  6940.        $>GROB          ( $ --> grob ) ( 5x7 font )
  6941.        $>grob          ( $ --> grob ) ( 3x7 font )
  6942.        DOLCD>          ( --> 64x131grob )
  6943.        GROB!           ( grob1 grob2 #col #row --> )
  6944.                          Stores grob1 into grob2. This is a
  6945.                          bang-type word with no error checks!
  6946.        GROB!ZERO       ( grob #x1 #y1 #x2 #y2 --> grob' )
  6947.                          Zeros out a rectangular section of a
  6948.                          grob.  NOTE: Bang-type operation.
  6949.        GROB!ZERODRP    ( grob #x1 #y1 #x2 #y2 --> )
  6950.                          Zeros out a rectangular section of a
  6951.                          grob.  NOTE: Bang-type operation!
  6952.        GROB>GDISP      ( grob --> )
  6953.                          Stores graph grob with new grob.
  6954.        HARDBUFF        ( --> HBgrob (the current display grob) )
  6955.        HEIGHTENGROB    ( grob #rows --> )
  6956.                          Adds #rows to grob, unless grob is null.
  6957.                          NOTE: Assumes text grob or graph grob!
  6958.        INVGROB         ( grob --> grob' )
  6959.                          Invert grob data bits - bang-type.
  6960.        LINEOFF         ( #x1 #y1 #x2 #y2 --> )
  6961.                          Clears pixels in a line in text grob
  6962.                          Note: #x2 must be > #x1 (use ORDERXY#)
  6963.        LINEOFF3        ( #x1 #y1 #x2 #y2 --> )
  6964.                          Clears pixels in a line in graph grob
  6965.                          Note: #x2 must be > #x1 (use ORDERXY#)
  6966.        LINEON          ( #x1 #y1 #x2 #y2 --> )
  6967.                          Sets pixels in a line in text grob
  6968.                          Note: #x2 must be > #x1 (use ORDERXY#)
  6969.        LINEON3         ( #x1 #y1 #x2 #y2 --> )
  6970.                          Sets pixels in a line in graph grob
  6971.                          Note: #x2 must be > #x1 (use ORDERXY#)
  6972.        MAKEGROB        ( #height #width --> grob )
  6973.        ORDERXY#        ( #x1 #y1 #x2 #y2 --> #x1 #y1 #x2 #y2 )
  6974.                          Orders two points for line drawing
  6975.        PIXOFF          ( #x #y --> )
  6976.                          Clears a pixel in the text grob
  6977.        PIXOFF3         ( #x #y --> )
  6978.                          Clears a pixel in the graph grob
  6979.        PIXON           ( #x #y --> )
  6980.                          Sets a pixel in the text grob
  6981.        PIXON?          ( #x #y --> flag )
  6982.                          Returns TRUE if text grob pixel is set
  6983.        PIXON?3         ( #x #y --> flag )
  6984.                          Returns TRUE if graph grob pixel is set
  6985.        PIXON3          ( #x #y --> )
  6986.                          Sets a pixel in the graph grob
  6987.        SUBGROB         ( grob #x1 #y1 #x2 #y2 --> subgrob )
  6988.        Symb>HBuff      ( symb --> )
  6989.                          Displays symb in HARDBUFF in Equation-
  6990.                          Writer form.  May enlarge HARDBUFF, so
  6991.                          do RECLAIMDISP afterwards.
  6992.  
  6993.  
  6994.  
  6995.                                  Page 103
  6996.  
  6997.  
  6998.  
  6999.  
  7000.  
  7001.  
  7002.        TOGLINE         ( #x1 #y1 #x2 #y2 --> )
  7003.                          Toggles pixels in a line in text grob
  7004.        TOGLINE3        ( #x1 #y1 #x2 #y2 --> )
  7005.                          Toggles pixels in a line in graph grob
  7006.  
  7007.        NOTE: #x2 must be greater than #x1 for line drawing!
  7008.  
  7009.  
  7010.        20.8.3  Grob_Dimensions
  7011.  
  7012.        The following words return or verify size information:
  7013.  
  7014.        CKGROBFITS      ( grob1 grob2 #n #m --> grob1 grob2' #n #m )
  7015.                          Truncates grob2 if it doesn't fit in grob1
  7016.        DUPGROBDIM      ( grob --> grob #height #width )
  7017.        GBUFFGROBDIM    ( --> #height #width )
  7018.                          Returns dimensions of graph grob
  7019.        GROBDIM         ( grob --> #height #width )
  7020.        GROBDIMw        ( grob --> #width )
  7021.  
  7022.  
  7023.        20.8.4  Built-in_Grobs
  7024.  
  7025.        The following words refer to built-in grobs:
  7026.  
  7027.        BigCursor       5x9 Cursor (outline box)
  7028.        CROSSGROB       5x5 "+" symbol
  7029.        CURSOR1         5x9 Insert Cursor (arrow)
  7030.        CURSOR2         5x9 Replace Cursor (solid box)
  7031.        MARKGROB        5x5 "X" symbol
  7032.        MediumCursor    5x7 Cursor (outline box)
  7033.        SmallCursor     3x5 Cursor (outline box)
  7034.  
  7035.  
  7036.  
  7037.  
  7038.  
  7039.  
  7040.  
  7041.  
  7042.  
  7043.  
  7044.  
  7045.  
  7046.  
  7047.  
  7048.  
  7049.  
  7050.  
  7051.  
  7052.  
  7053.  
  7054.  
  7055.  
  7056.  
  7057.  
  7058.  
  7059.  
  7060.  
  7061.                                  Page 104
  7062.  
  7063.  
  7064.  
  7065.  
  7066.  
  7067.  
  7068.        20.8.5  Menu_Display_Utilities
  7069.  
  7070.        Menu labels are grobs which are 8 rows high and 21 pixels
  7071.        wide.  The columns for menu key labels in HARDBUFF2 are:
  7072.  
  7073.                ZERO            Softkey 1
  7074.                TWENTYTWO       Softkey 2
  7075.                # 0002C         Softkey 3
  7076.                # 00042         Softkey 4
  7077.                # 00058         Softkey 5
  7078.                # 0006E         Softkey 6
  7079.  
  7080.        The routine DispMenu.1 redisplays the current menu; the
  7081.        routine DispMenu redisplays the current menu and also calls
  7082.        SetDA3Valid to "freeze" the menu display line.
  7083.  
  7084.        The following words convert objects to menu labels and
  7085.        display the labels at the given column number:
  7086.  
  7087.        Grob>Menu       ( #col 8x21grob --> )
  7088.                          Displays an 8x21 (only!) grob
  7089.        Id>Menu         ( #col Id --> )
  7090.                          Recalls Id and displays standard label
  7091.                          or directory label, depending on the
  7092.                          contents of Id.
  7093.        Seco>Menu       ( #col seco --> )
  7094.                          Evaluates secondary and uses result to
  7095.                          produce and display appropriate menu label
  7096.        Str>Menu        ( #col $ --> )
  7097.                          Makes and displays standard menu label
  7098.  
  7099.        The following words convert strings to the different kinds
  7100.        of available menu key grobs:
  7101.  
  7102.        MakeBoxLabel    ( $ --> grob ) Box with bullet in it
  7103.        MakeDirLabel    ( $ --> grob ) Box with directory bar
  7104.        MakeInvLabel    ( $ --> grob ) White label (solver)
  7105.        MakeStdLabel    ( $ --> grob ) Black label (standard)
  7106.  
  7107.  
  7108.        20.9  Scrolling the Display
  7109.  
  7110.        The following words are available for scrolling the display:
  7111.  
  7112.        SCROLLDOWN      ( *Scroll down one pixel with repeat* )
  7113.        SCROLLLEFT      ( *Scroll left one pixel with repeat* )
  7114.        SCROLLRIGHT     ( *Scroll right one pixel with repeat* )
  7115.        SCROLLUP        ( *Scroll up one pixel with repeat* )
  7116.  
  7117.        JUMPBOT         ( *Move window to bottom edge of grob* )
  7118.        JUMPLEFT        ( *Move window to left edge of grob* )
  7119.        JUMPRIGHT       ( *Move window to right edge of grob* )
  7120.        JUMPTOP         ( *Move window to bottom edge of grob* )
  7121.  
  7122.        The SCROLL* words test to see if their corresponding arrow
  7123.        key is being held down, and repeat their action until the
  7124.  
  7125.  
  7126.  
  7127.                                  Page 105
  7128.  
  7129.  
  7130.  
  7131.  
  7132.  
  7133.  
  7134.        edge of the grob is reached or the key released.
  7135.  
  7136.        The example below illustrates a series of graphics
  7137.        operations and the use of a Parameterized Outer Loop which
  7138.        provides scrolling for the user.
  7139.  
  7140.        *---------------------------------------------------------
  7141.  
  7142.        *
  7143.        * Include the header file KEYDEFS.H, which defines words
  7144.        * like kcUpArrow at physical key numbers.
  7145.        *
  7146.        INCLUDE KEYDEFS.H
  7147.        *
  7148.        * Include the eight characters needed for binary download
  7149.        *
  7150.        ASSEMBLE
  7151.                NIBASC  /HPHP48-D/
  7152.        RPL
  7153.        *
  7154.        * Begin the secondary
  7155.        *
  7156.        ::
  7157.          RECLAIMDISP           ( *Claim the alpha display* )
  7158.          ClrDA1IsStat          ( *Temporarily disable clock* )
  7159.        *                       ( *Try removing ClrDA1IsStat* )
  7160.          ZEROZERO              ( #0 #0 )
  7161.          150 150 MAKEGROB      ( #0 #0 150x150grob )
  7162.          XYGROBDISP            (  )
  7163.          TURNMENUOFF           ( *Turn off menu line* )
  7164.        *
  7165.        * Draw diagonal lines.  Remember that LINEON requires
  7166.        * requires #x2>#x1!
  7167.        *
  7168.          ZEROZERO              ( #x1 #y1 )
  7169.          149 149               ( #x1 #y1 #x2 #y2 )
  7170.          LINEON                ( *Draw line* )
  7171.          ZERO 149              ( #x1 #y1 )
  7172.          149 ZERO              ( #x1 #y1 #x2 #y2 )
  7173.          LINEON                ( *Draw line* )
  7174.        *
  7175.        * Place text
  7176.        *
  7177.          HARDBUFF
  7178.          75 50 "SCROLLING"     ( HBgrob 75 150 "SCROLLING" )
  7179.          150 CENTER$3x5        ( HBgrob )
  7180.          75 100 "EXAMPLE"      ( HBgrob 75 100 "EXAMPLE" )
  7181.          150 CENTER$3x5        ( HBgrob )
  7182.          DROPFALSE             ( FALSE )
  7183.          { LAM Exit } BIND     ( *Bind POL exit flag* )
  7184.          ' NOP                 ( *No display action*  )
  7185.          ' ::                  ( *Hard key handler*   )
  7186.            kpNoShift #=casedrop
  7187.              ::
  7188.                 kcUpArrow    ?CaseKeyDef
  7189.                                  :: TakeOver SCROLLUP ;
  7190.  
  7191.  
  7192.  
  7193.                                  Page 106
  7194.  
  7195.  
  7196.  
  7197.  
  7198.                 kcLeftArrow  ?CaseKeyDef
  7199.                                  :: TakeOver SCROLLLEFT ;
  7200.                 kcDownArrow  ?CaseKeyDef
  7201.                                  :: TakeOver SCROLLDOWN ;
  7202.                 kcRightArrow ?CaseKeyDef
  7203.                                  :: TakeOver SCROLLRIGHT ;
  7204.                 kcOn         ?CaseKeyDef
  7205.                                  :: TakeOver
  7206.                                     TRUE ' LAM Exit STO ;
  7207.                 kcRightShift   #=casedrpfls
  7208.                 DROP 'DoBadKeyT
  7209.              ;
  7210.            kpRightShift #=casedrop
  7211.              ::
  7212.                 kcUpArrow    ?CaseKeyDef
  7213.                                  :: TakeOver JUMPTOP ;
  7214.                 kcLeftArrow  ?CaseKeyDef
  7215.                                  :: TakeOver JUMPLEFT ;
  7216.                 kcDownArrow  ?CaseKeyDef
  7217.                                  :: TakeOver JUMPBOT ;
  7218.                 kcRightArrow ?CaseKeyDef
  7219.                                  :: TakeOver JUMPRIGHT ;
  7220.                 kcRightShift #=casedrpfls
  7221.                 DROP 'DoBadKeyT
  7222.              ;
  7223.            2DROP 'DoBadKeyT
  7224.          ;
  7225.          TrueTrue              ( *Key control flags* )
  7226.          NULL{}                ( *No softkeys here*  )
  7227.          ONEFALSE              ( *1st row, no suspend* )
  7228.          ' LAM Exit            ( *App exit condition* )
  7229.          ' ERRJMP              ( *Error handler* )
  7230.          ParOuterLoop          ( *Run the ParOuterLoop* )
  7231.          TURNMENUON            ( *Restore menu row* )
  7232.          RECLAIMDISP           ( *Resize and clear display* )
  7233.        ;
  7234.  
  7235.  
  7236.  
  7237.  
  7238.  
  7239.  
  7240.  
  7241.  
  7242.  
  7243.  
  7244.  
  7245.  
  7246.  
  7247.  
  7248.  
  7249.  
  7250.  
  7251.  
  7252.  
  7253.  
  7254.  
  7255.  
  7256.  
  7257.  
  7258.  
  7259.                                  Page 107
  7260.  
  7261.  
  7262.  
  7263.  
  7264.        The above code, if stored in a file SCROLL.S, can be
  7265.        compiled as follows:
  7266.  
  7267.        RPLCOMPILE SCROLL.S
  7268.        SASM SCROLL.A
  7269.        SLOAD -H SCROLL.M
  7270.  
  7271.        This example also assumes that the file KEYDEFS.H is either
  7272.        in the same directory or the source file has been modified
  7273.        to reflect the location of KEYDEFS.H.  The loader control
  7274.        file SCROLL.M looks like this:
  7275.  
  7276.        OU SCROLL
  7277.        LL SCROLL.LR
  7278.        SU XR
  7279.        SE ENTRIES.O
  7280.        RE SCROLL.O
  7281.  
  7282.        The final file, SCROLL, may be binary downloaded to the
  7283.        HP 48 for a test.
  7284.  
  7285.        When SCROLL is running, the arrow keys scroll the display,
  7286.        and the right-shifted arrow keys move the window to the
  7287.        corresponding boundary.  The [ATTN] key terminates the
  7288.        program.
  7289.  
  7290.        For more details on the ParOuterLoop, see the chapter
  7291.        "Keyboard Control".
  7292.  
  7293.  
  7294.  
  7295.  
  7296.  
  7297.  
  7298.  
  7299.  
  7300.  
  7301.  
  7302.  
  7303.  
  7304.  
  7305.  
  7306.  
  7307.  
  7308.  
  7309.  
  7310.  
  7311.  
  7312.  
  7313.  
  7314.  
  7315.  
  7316.  
  7317.  
  7318.  
  7319.  
  7320.  
  7321.  
  7322.  
  7323.  
  7324.  
  7325.                                  Page 108
  7326.  
  7327.  
  7328.  
  7329.  
  7330.        21.  Keyboard Control
  7331.  
  7332.        A program that requires keyboard input from the user may
  7333.        choose from three basic techniques available with internal
  7334.        RPL, listed in order of increasing complexity:
  7335.  
  7336.  
  7337.          1.  Wait for an individual keystroke, then decide what to
  7338.              do with it.
  7339.  
  7340.          2.  Call the internal form of INPUT.
  7341.  
  7342.          3.  Set up a Parameterized Outer Loop to control an entire
  7343.              application environment.
  7344.  
  7345.        The following sections discuss the internal numbering scheme
  7346.        for keys and each of the above three key processing
  7347.        strategies.
  7348.  
  7349.  
  7350.        21.1  Key Locations
  7351.  
  7352.        The user word WAIT returns a real number which is encoded in
  7353.        the form rc.p, where:
  7354.  
  7355.                          r = The row of the key
  7356.                          c = The column of the key
  7357.                          p = The shift plane.
  7358.  
  7359.           +--------+----------------+---+---------------------+
  7360.           |   p    | Primary Planes | p |     Alpha Planes    |
  7361.           +--------+----------------+---+---------------------+
  7362.           | 0 or 1 | Unshifted      | 4 | Alpha               |
  7363.           |   2    | Left-shifted   | 5 | Alpha left-shifted  |
  7364.           |   3    | Right-shifted  | 6 | Alpha right-shifted |
  7365.           +--------+----------------+---+---------------------+
  7366.  
  7367.  
  7368.        Internally, key locations are represented with two binary
  7369.        integers: #KeyCode, which defines a physical key, and
  7370.        #Plane, which defines the shift plane.
  7371.  
  7372.        The file KEYDEFS.H, supplied with the RPL compiler, defines
  7373.        the following terms for key planes:
  7374.  
  7375.        DEFINE  kpNoShift        ONE
  7376.        DEFINE  kpLeftShift      TWO
  7377.        DEFINE  kpRightShift     THREE
  7378.        DEFINE  kpANoShift       FOUR
  7379.        DEFINE  kpALeftShift     FIVE
  7380.        DEFINE  kpARightShft     SIX
  7381.  
  7382.  
  7383.  
  7384.  
  7385.  
  7386.  
  7387.  
  7388.  
  7389.  
  7390.  
  7391.                                  Page 109
  7392.  
  7393.  
  7394.  
  7395.  
  7396.  
  7397.  
  7398.        Keys are numbered internally from 1 to 49, starting at the
  7399.        upper left corner of the keyboard.  Primary key definitions
  7400.        are also provided in KEYDEFS.H.  Here are a few of them:
  7401.  
  7402.        DEFINE  kcMenuKey1       ONE
  7403.        DEFINE  kcMenuKey2       TWO
  7404.        DEFINE  kcMenuKey3       THREE
  7405.        DEFINE  kcMenuKey4       FOUR
  7406.        DEFINE  kcMenuKey5       FIVE
  7407.        DEFINE  kcMenuKey6       SIX
  7408.        DEFINE  kcMathMenu       SEVEN
  7409.        DEFINE  kcPrgmMenu       EIGHT
  7410.        DEFINE  kcCustomMenu     NINE
  7411.             ...
  7412.        DEFINE  KcPlus           FORTYNINE
  7413.  
  7414.        The use of these definitions in source code is encouraged
  7415.        for legibility.
  7416.  
  7417.        The translation between internal key numbering and rc.p
  7418.        numbering may be carried out with two words:
  7419.  
  7420.        Ck&DecKeyLoc    ( %rc.p --> #KeyCode #Plane )
  7421.        CodePl>%rc.p    ( #KeyCode #Plane --> %rc.p )
  7422.  
  7423.  
  7424.        21.2  Waiting for a Key
  7425.  
  7426.        If an application needs to wait for a single key, such as a
  7427.        yes-no-attn type decision, it is best to use the word
  7428.        WaitForKey, which returns a fully formed keystroke.
  7429.        WaitForKey also keeps the HP 48 in a low-power state until a
  7430.        key is pressed and handles the alpha and shift annunciators
  7431.        and alarm processing.
  7432.  
  7433.        The following words are available:
  7434.  
  7435.        CHECKKEY        ( --> #KeyCode TRUE )
  7436.                        ( --> FALSE )
  7437.                          Returns, but does not pop, the next
  7438.                          key in the buffer.
  7439.        FLUSHKEYS       ( --> )
  7440.                          Flush the key buffer.
  7441.        GETTOUCH        ( --> #KeyCode TRUE )
  7442.                        ( --> FALSE )
  7443.                          Pops next key from buffer.
  7444.        KEYINBUFFER?    ( --> FLAG )
  7445.                          Returns TRUE if a key is in the buffer,
  7446.                          otherwise returns FALSE.
  7447.        ATTN?           ( --> flag )
  7448.                          Returns TRUE if [ATTN] has been pressed
  7449.        ATTNFLGCLR      ( --> )
  7450.                          Clears the attn key flag (does not
  7451.                          flush attn key from buffer)
  7452.        WaitForKey      ( --> #KeyCode #Plane )
  7453.                          Returns next fully formed keystroke.
  7454.  
  7455.  
  7456.  
  7457.                                  Page 110
  7458.  
  7459.  
  7460.  
  7461.  
  7462.  
  7463.  
  7464.        21.3  InputLine
  7465.  
  7466.        The word InputLine is the core of the user word INPUT as
  7467.        well as the prompt for equation names (NEW).  InputLine does
  7468.        the following:
  7469.  
  7470.         + Displays the prompt in display area 2a,
  7471.  
  7472.         + Sets the keyboard entry modes,
  7473.  
  7474.         + Initializes the edit line,
  7475.  
  7476.         + Accepts user input until [ENTER] is either explicitly or
  7477.           implicitly pressed,
  7478.  
  7479.         + Parses, evaluates, or just returns the user-input edit
  7480.           line,
  7481.  
  7482.         + Returns TRUE if exited by Enter or FALSE if aborted by
  7483.           Attn.
  7484.  
  7485.        The stack on entry must contain the following:
  7486.  
  7487.         $Prompt    The prompt to be displayed during user input
  7488.         $EditLine  The initial edit line
  7489.         CursorPos  The initial edit line cursor position, specified
  7490.                    as a binary integer character number or a two-
  7491.                    element list of binary integer row and column
  7492.                    numbers.  For all numbers, #0 indicates the end
  7493.                    of the edit line, row, or column.
  7494.         #Ins/Rep   The initial insert/replace mode:
  7495.                      #0    current insert/replace mode
  7496.                      #1    insert mode
  7497.                      #2    replace mode
  7498.         #Entry     The initial entry mode:
  7499.                      #0    current entry mode plus program entry
  7500.                      #1    program/immediate entry
  7501.                      #2    program/algebraic entry
  7502.         #AlphaLock The initial alpha-lock mode:
  7503.                      #0    current alpha lock mode
  7504.                      #1    alpha lock enabled
  7505.                      #2    alpha lock disabled
  7506.         ILMenu     The initial InputLine menu in the format
  7507.                    specified by "ParOuterLoop"
  7508.         #ILMenuRow The initial InputLine menu row number in the
  7509.                    format specified by "ParOuterLoop"
  7510.         AttnAbort? A flag specifying whether pressing Attn while
  7511.                    a non-null edit line exists should abort
  7512.                    "InputLine" (TRUE) or just clear the edit
  7513.                    line (FALSE)
  7514.         #Parse     How to process the resulting edit line:
  7515.                      #0    Return the edit line as a string
  7516.                      #1    Return the edit line as a string AND
  7517.                            as a parsed object
  7518.                      #2    Parse and evaluate the edit line
  7519.  
  7520.  
  7521.  
  7522.  
  7523.                                  Page 111
  7524.  
  7525.  
  7526.  
  7527.  
  7528.  
  7529.  
  7530.        InputLine returns different results, depending on the
  7531.        initial value of #Parse:
  7532.  
  7533.         #Parse  Stack              Description
  7534.         ------  -----------------  ------------------------------
  7535.           #0    $EditLine TRUE     Edit line
  7536.           #1    $EditLine ob TRUE  Edit line and parsed edit line
  7537.           #2    Ob1 ... Obn TRUE   Resulting object or objects
  7538.                 FALSE              Attn pressed to abort edit
  7539.  
  7540.  
  7541.  
  7542.        21.3.1  InputLine_Example
  7543.  
  7544.        The example call to InputLine shown below prompts the user
  7545.        for a variable name. If the user enters a valid name, the
  7546.        name and TRUE are returned, otherwise FALSE is returned.
  7547.  
  7548.          ( --> Ob TRUE | FALSE )
  7549.        ::
  7550.          "Enter name:" ( *Prompt string* )
  7551.          NULL$         ( *No default name* )
  7552.          ONEONE        ( *Initial edit line & cursor pos* )
  7553.          ONEONE        ( *Insert mode & prog/immed. entry* )
  7554.          NULL{}        ( *No edit menu* )
  7555.          ONE           ( *Menu row* )
  7556.          FALSE         ( *Attn clears edit line* )
  7557.          ONE           ( *Return edit line and parsed ob* )
  7558.          InputLine     ( ($editline ob TRUE) | (FALSE) )
  7559.          NOTcaseFALSE  ( *Exit if Attn pressed* )
  7560.          SWAP NULL$?   ( *Exit if blank edit line* )
  7561.          casedrop FALSE
  7562.          DUPTYPEIDNT?  ( *Check if ob is id* )
  7563.          caseTRUE      ( *Yes, exit true* )
  7564.          DROPFALSE     ( *No, drop ob and FALSE* )
  7565.        ;
  7566.  
  7567.  
  7568.  
  7569.  
  7570.  
  7571.  
  7572.  
  7573.  
  7574.  
  7575.  
  7576.  
  7577.  
  7578.  
  7579.  
  7580.  
  7581.  
  7582.  
  7583.  
  7584.  
  7585.  
  7586.  
  7587.  
  7588.  
  7589.                                  Page 112
  7590.  
  7591.  
  7592.  
  7593.  
  7594.  
  7595.  
  7596.        21.4  The Parameterized Outer Loop
  7597.  
  7598.        In this section, the term "parameterized outer loop" is used
  7599.        to refer to a usage of the RPL word "ParOuterLoop", or a
  7600.        combined usage of its fundamental component utilities
  7601.        (described below), all of which can be envisioned as words
  7602.        that take over the keyboard and display until a specified
  7603.        condition is met.
  7604.  
  7605.        The parameterized outer loop, "ParOuterLoop", takes nine
  7606.        arguments, in order:
  7607.  
  7608.           AppDisplay The display update object to be evaluated
  7609.                     before each key evaluation.  "AppDisplay"
  7610.                     should handle display updating not handled by
  7611.                     the keys themselves, and should also perform
  7612.                     special handling of errors.
  7613.  
  7614.           AppKeys   The hard key assignments, a secondary object in
  7615.                     the format described below.
  7616.  
  7617.           NonAppKeyOK? A flag specifying whether the hard keys not
  7618.                     assigned by the application should perform
  7619.                     their default actions or be canceled.
  7620.  
  7621.           DoStdKeys? A flag used in conjunction with "NonAppKeyOK?"
  7622.                     specifying whether standard key definitions are
  7623.                     to be used for non-application keys instead of
  7624.                     default key processing.
  7625.  
  7626.           AppMenu   The menu key specification, a secondary or list
  7627.                     in the format specified in the menu key
  7628.                     assignments document, or FALSE.
  7629.  
  7630.           #AppMenuRow The initial application menu row number.  For
  7631.                     most applications, this should be binary
  7632.                     integer one.
  7633.  
  7634.           SuspendOK? A flag specifying whether or not any user
  7635.                     command that would create a suspended
  7636.                     environment and restart the system outer loop
  7637.                     should instead generate an error.
  7638.  
  7639.           ExitCond  An object that evaluates to TRUE when the outer
  7640.                     loop is to be exited, or FALSE otherwise.
  7641.                     "ExitCond" is evaluated before each application
  7642.                     display update and key evaluation.
  7643.  
  7644.           AppError  The error-handling object to be evaluated if an
  7645.                     error occurs during the key evaluation part of
  7646.                     the parameterized outer loop.
  7647.  
  7648.        The parameterized outer loop itself returns no results.
  7649.        However, any of the keys used by the application can return
  7650.        results to the data stack or in any manner desired.
  7651.  
  7652.  
  7653.  
  7654.  
  7655.                                  Page 113
  7656.  
  7657.  
  7658.  
  7659.  
  7660.  
  7661.  
  7662.  
  7663.        21.4.1  The_Parameterized_Outer_Loop_Utilities
  7664.  
  7665.        The parameterized outer loop word "ParOuterLoop" consists
  7666.        entirely of calls (with proper error handling) to its four
  7667.        RPL utility words, in order:
  7668.  
  7669.           POLSaveUI Saves the current user interface in a temporary
  7670.                     environment.  Takes no arguments and returns no
  7671.                     results.
  7672.  
  7673.           POLSetUI  Sets the current user interface according to
  7674.                     the same parameters required by "ParOuterLoop".
  7675.                     Returns no results.
  7676.  
  7677.           POLKeyUI  Displays, reads and evaluates keys, handles
  7678.                     errors, and exits according to the user
  7679.                     interface specified by "POLSetUI".  Takes no
  7680.                     arguments and returns no results.
  7681.  
  7682.           POLRestoreUI Restores the user interface saved by
  7683.                     "POLSaveUI" and abandons the temporary
  7684.                     environment.  Takes no arguments and returns no
  7685.                     results.
  7686.  
  7687.        (In addition to the four utilities above. utility
  7688.        "POLResUI&Err" is used to protect the saved user interface
  7689.        in the event of an error that's not handled within the
  7690.        parameterized outer loop.  Refer to "Parameterized Outer
  7691.        Loop Operation" and "Handling Errors with the Utilities",
  7692.        below.)
  7693.  
  7694.        These utilities can be used by applications that require
  7695.        greater control over the user interface.  For example:
  7696.  
  7697.           + For optimum performance an application can create a
  7698.             temporary environment with null-named temporary
  7699.             variables after calling "POLSaveUI", then access the
  7700.             null-named variables "within" "POLKeyUI", since only
  7701.             "POLSaveUI" creates a parameterized outer loop
  7702.             temporary environment and only "POLRestoreUI" accesses
  7703.             the same environment.
  7704.  
  7705.           + To avoid unnecessary and time-consuming overhead, an
  7706.             application that uses multiple consecutive (not nested)
  7707.             parameterized outer loops can call "POLSaveUI" at the
  7708.             start of the application, then call "POLSetUI" and
  7709.             "POLKeyUI" multiple times throughout the application,
  7710.             then finally call "POLRestoreUI" at the end of the
  7711.             application.
  7712.  
  7713.  
  7714.  
  7715.  
  7716.  
  7717.  
  7718.  
  7719.  
  7720.  
  7721.                                  Page 114
  7722.  
  7723.  
  7724.  
  7725.  
  7726.  
  7727.  
  7728.        21.4.2  Overview_of_the_Parameterized_Outer_Loop
  7729.  
  7730.        The parameterized outer loop operates as outlined below.
  7731.  
  7732.             ("POLSaveUI")
  7733.             Save the system or current application's
  7734.             user interface
  7735.  
  7736.             If error in
  7737.  
  7738.               ("POLSetUI")
  7739.               Set the new application's user interface
  7740.  
  7741.               ("POLKeyUI")
  7742.               While "ExitCond" evaluates to FALSE {
  7743.                 Evaluate "AppDisplay"
  7744.                 If error in
  7745.                   Read and evaluate a key
  7746.                 Then
  7747.                   Evaluate "AppError"
  7748.                 }
  7749.  
  7750.             Then
  7751.  
  7752.               Restore the saved user interface and
  7753.               ERRJMP
  7754.  
  7755.             ("POLRestoreUI")
  7756.             Restore the saved user interface
  7757.  
  7758.        The parameterized outer loop creates one temporary
  7759.        environment when it saves the current user interface, and it
  7760.        abandons this environment when it restores a saved user
  7761.        interface.  This means that words that operate on the
  7762.        topmost temporary environment, such as "1GETLAM", should NOT
  7763.        be used "within" the parameterized outer loop (e.g., in a
  7764.        key definition or the application display update object)
  7765.        UNLESS the desired temporary environment is created AFTER
  7766.        calling "POLSaveUI" and abandoned before calling
  7767.        "POLRestoreUI".  For temporary environments created before
  7768.        calling the parameterized outer loop, applications should
  7769.        set up and operate on NAMED temporary variables.
  7770.  
  7771.  
  7772.  
  7773.  
  7774.  
  7775.  
  7776.  
  7777.  
  7778.  
  7779.  
  7780.  
  7781.  
  7782.  
  7783.  
  7784.  
  7785.  
  7786.  
  7787.                                  Page 115
  7788.  
  7789.  
  7790.  
  7791.  
  7792.  
  7793.  
  7794.        21.4.3  Handling_Errors_with_the_Utilities
  7795.  
  7796.        To insure that it can properly restore a saved user
  7797.        interface if an error occurs within an application, the
  7798.        parameterized outer loop protects the saved user interface
  7799.        by setting an error trap immediately after its call to
  7800.        "POLSaveUI", as shown below:
  7801.  
  7802.        ::
  7803.          POLSaveUI             ( save the current user interface )
  7804.          ERRSET                ( prepare to restore saved user interface
  7805.                                in case of error )
  7806.            ::
  7807.              POLSetUI          ( set the application's user interface )
  7808.              POLKeyUI          ( display, read, and evaluate )
  7809.            ;
  7810.          ERRTRAP               ( if error, then restore the saved
  7811.                                user interface and error )
  7812.            POLResUI&Err
  7813.          POLRestoreUI          ( restore the saved user interface )
  7814.        ;
  7815.  
  7816.  
  7817.        The purpose of supported utility "POLResUI&Err" is to
  7818.        restore the user interface saved by "POLSaveUI" and then to
  7819.        error.
  7820.  
  7821.        Any applications that use the parameterized outer loop
  7822.        utilities instead of "ParOuterLoop" are REQUIRED to include
  7823.        this same level of error handling protection of the saved
  7824.        user interface.
  7825.  
  7826.  
  7827.        21.4.4  The_Display
  7828.  
  7829.        There is no default display in the parameterized outer loop;
  7830.        the application is responsible for setting up the initial
  7831.        display and updating it.
  7832.  
  7833.        There are two ways that an application can update the
  7834.        display: with outer loop parameter "AppDisplay" or with key
  7835.        assignments.  For example, if the user presses the right-
  7836.        arrow key to move a highlight from one matrix column to
  7837.        another, the key assignment for the right-arrow key can
  7838.        either pass information to "AppDisplay" (often implicitly)
  7839.        to handle the change, or the key assignment object can
  7840.        change the display itself.  Both methods have advantages
  7841.        under different circumstances.
  7842.  
  7843.  
  7844.  
  7845.  
  7846.  
  7847.  
  7848.  
  7849.  
  7850.  
  7851.  
  7852.  
  7853.                                  Page 116
  7854.  
  7855.  
  7856.  
  7857.  
  7858.  
  7859.  
  7860.        21.4.5  Error_Handling
  7861.  
  7862.        The error-handling outer loop parameter "AppError" is
  7863.        responsible for processing any errors generated during key
  7864.        evaluation within the parameterized outer loop. If an error
  7865.        occurs, "AppError" is evaluated.  "AppError" should
  7866.        determine the specific error and act accordingly. If an
  7867.        application can not handle any errors, then "AppError"
  7868.        should be specified as "ERRJMP".
  7869.  
  7870.  
  7871.        21.4.6  Hard_Key_Assignments
  7872.  
  7873.        Any HP 48 key, in any of the six planes (unshifted, left-
  7874.        shifted, right-shifted, alpha-unshifted, alpha-left-shifted,
  7875.        and alpha-right-shifted) can be assigned for the duration of
  7876.        the parameterized outer loop. The outer loop parameter
  7877.        "AppKeys" specifies the keys to assign and their new
  7878.        assignments.
  7879.  
  7880.        If a key is not assigned by an application, and outer loop
  7881.        parameter "NonAppKeyOK?" is TRUE, then standard or default
  7882.        key processing occurs, according to outer loop parameter
  7883.        "DoStdKeys?".  For example, if user keys mode is on and the
  7884.        key has a user key assignment, then the user key is
  7885.        processed if "DoStdKeys?" is FALSE, or the standard key is
  7886.        processed if "DoStdKeys?" is TRUE. If "NonAppKeyOK?" is
  7887.        FALSE, then all non-application keys issue a canceled key
  7888.        warning beep and do nothing else.
  7889.  
  7890.        In general, NonAppKeyOK? should be FALSE to maintain total
  7891.        control.
  7892.  
  7893.  
  7894.  
  7895.  
  7896.  
  7897.  
  7898.  
  7899.  
  7900.  
  7901.  
  7902.  
  7903.  
  7904.  
  7905.  
  7906.  
  7907.  
  7908.  
  7909.  
  7910.  
  7911.  
  7912.  
  7913.  
  7914.  
  7915.  
  7916.  
  7917.  
  7918.  
  7919.                                  Page 117
  7920.  
  7921.  
  7922.  
  7923.  
  7924.  
  7925.  
  7926.        Application key assignments are specified by the secondary
  7927.        object "AppKeys" passed to the parameterized outer loop.
  7928.        The procedure must take as its arguments a key code and a
  7929.        plane specification, and must return the desired key
  7930.        definition and TRUE if the application defines the key, or
  7931.        FALSE if the application doesn't.  Specifically, the key
  7932.        assignment procedure's stack diagram must look like this:
  7933.  
  7934.             ( #KeyCode #Plane --> KeyDef TRUE )
  7935.             ( #KeyCode #Plane --> FALSE )
  7936.  
  7937.        The key definition result "KeyDef" will be processed by the
  7938.        main key handler, "DoKeyOb".
  7939.  
  7940.        Application key assignments specified as procedures
  7941.        generally have logic in the form
  7942.  
  7943.             If #Plane is NoShift  (or first plane of interest)
  7944.             Then
  7945.               Process #KeyCode in the unshifted plane
  7946.               Else
  7947.                 If #Plane is LeftShift  (or next plane of interest)
  7948.                 Then
  7949.                   Process #KeyCode in the left-shifted plane
  7950.               ...
  7951.                   Else signal no definition
  7952.  
  7953.        This can be implemented in RPL in the form
  7954.  
  7955.             kpNoShift   #=casedrop :: (process noshift plane) ;
  7956.             kpLeftShift #=casedrop :: (process l-shift plane) ;
  7957.             2DROP FALSE
  7958.  
  7959.        Each plane handler generally has logic in the form
  7960.  
  7961.             If #KeyCode is 7  (or first key code of interest)
  7962.             Then
  7963.               Return the key code 7 definition and TRUE
  7964.             Else
  7965.               If #KeyCode is 20  (or next key code of interest)
  7966.               Then
  7967.                 Return the key code 20 definition and TRUE
  7968.                 Else signal no definition
  7969.  
  7970.        This can be implemented in RPL in the following form:
  7971.  
  7972.             kcMathMenu ?CaseKeyDef :: TakeOver (process MTH) ;
  7973.             kcTan      ?CaseKeyDef :: TakeOver (process TAN) ;
  7974.             ( all other keys )
  7975.             DROP FALSE
  7976.  
  7977.  
  7978.  
  7979.  
  7980.  
  7981.  
  7982.  
  7983.  
  7984.  
  7985.                                  Page 118
  7986.  
  7987.  
  7988.  
  7989.  
  7990.  
  7991.  
  7992.        In order to save code and to make key definitions more
  7993.        readable, the control structure word "?CaseKeyDef" replaces
  7994.        the
  7995.  
  7996.             #=casedrop :: ' <KeyDef> TRUE ;
  7997.  
  7998.        portions of code with
  7999.  
  8000.             ?CaseKeyDef <KeyDef>
  8001.  
  8002.        More specifically, "?CaseKeyDef" is used in the form
  8003.  
  8004.              ... #KeyCode #TestKeyCode ?CaseKeyDef <KeyDef> ...
  8005.  
  8006.        If "#KeyCode" equals "#TestKeyCode", then "?CaseKeyDef"
  8007.        drops "#KeyCode" and "#TestKeyCode", pushes "KeyDef" and
  8008.        TRUE, and exits the calling secondary.  Otherwise,
  8009.        "?CaseKeyDef" drops "#TestKeyCode" only, skips "KeyDef", and
  8010.        continues.
  8011.  
  8012.  
  8013.        21.4.7  Menu_Key_Assignments
  8014.  
  8015.        An application can specify any initial menu key assignments,
  8016.        in any of three planes (unshifted, left-shifted, and right-
  8017.        shifted), to be initialized when the parameterized outer
  8018.        loop is started.  The outer loop parameter "AppMenu"
  8019.        specifies the initialization object (a list or secondary)
  8020.        for the application's menu, or FALSE, indicating that the
  8021.        current menu is to be left intact.  When the parameterized
  8022.        outer loop is exited, the previous menu is restored
  8023.        automatically.
  8024.  
  8025.        If "AppMenu" is a null list, then a set of six null menu key
  8026.        assignments are made.  If "AppMenu" is FALSE, then the menu
  8027.        present when the parameterized outer loop is called is
  8028.        maintained.
  8029.  
  8030.        NOTE: hard key assignments have priority over menu key
  8031.        assignments.  This means that the hard key handler must
  8032.        include the following line if menu keys are to be processed:
  8033.  
  8034.                 DUP#<7 casedrpfls
  8035.  
  8036.        The parameter AppMenu takes the following form:
  8037.  
  8038.        {
  8039.          Menu Key 1 Definition
  8040.          Menu Key 2 Definition
  8041.            ...
  8042.          Menu Key n Definition
  8043.        }
  8044.  
  8045.        Where each menu key definition takes one of three
  8046.        following forms:
  8047.  
  8048.  
  8049.  
  8050.  
  8051.                                  Page 119
  8052.  
  8053.  
  8054.  
  8055.  
  8056.  
  8057.  
  8058.          NullMenuKey
  8059.  
  8060.          { LabelObj :: TakeOver (Action) ; }
  8061.  
  8062.          { LabelObj {
  8063.                       :: TakeOver (Primary Action) ;
  8064.                       :: TakeOver (LeftShifted Action) ;
  8065.                     }
  8066.  
  8067.          { LabelObj {
  8068.                       :: TakeOver (Primary Action) ;
  8069.                       :: TakeOver (LfShifted Action) ;
  8070.                       :: TakeOver (RtShifted Action) ;
  8071.                     }
  8072.          }
  8073.  
  8074.        A LabelObj may be any object, but is usually a string or an
  8075.        8x21 grob. See the example below for an illustration of
  8076.        softkey use.  The word NullMenuKey inserts a blank menu key
  8077.        which just beeps when pressed.
  8078.  
  8079.  
  8080.  
  8081.        21.4.8  Preventing_Suspended_Environments
  8082.  
  8083.        An application may need to allow arbitrary commands and user
  8084.        objects to be evaluated, but don't want the current
  8085.        environment to be suspended by the "HALT" or "PROMPT"
  8086.        commands.  If the outer loop parameter "SuspendOK?" is
  8087.        FALSE, then any command that would suspend the environment
  8088.        generates a "HALT not Allowed" error, allowing "AppError" to
  8089.        handle it.  If "SuspendOK?" is TRUE, then the application
  8090.        must be prepared to handle the consequences. The dangers
  8091.        here are many and severe.
  8092.  
  8093.        For all foreseeable applications, "SuspendOK?" should be
  8094.        FALSE.
  8095.  
  8096.  
  8097.        21.4.9  Specifying_an_Exit_Condition
  8098.  
  8099.        The outer loop parameter "ExitCond" is an object that
  8100.        evaluates to TRUE when the outer loop is to exited, or FALSE
  8101.        otherwise.  "ExitCond" is evaluated before each key
  8102.        evaluation.
  8103.  
  8104.  
  8105.  
  8106.  
  8107.  
  8108.  
  8109.  
  8110.  
  8111.  
  8112.  
  8113.  
  8114.  
  8115.  
  8116.  
  8117.                                  Page 120
  8118.  
  8119.  
  8120.  
  8121.  
  8122.  
  8123.  
  8124.        21.4.10  ParOuterLoop_Example
  8125.  
  8126.        *---------------------------------------------------------
  8127.  
  8128.        *
  8129.        * Include the header file KEYDEFS.H, which defines words
  8130.        * like kcUpArrow at physical key numbers.
  8131.        *
  8132.        INCLUDE KEYDEFS.H
  8133.        *
  8134.        * Include the eight characters needed for binary download
  8135.        *
  8136.        ASSEMBLE
  8137.                NIBASC  /HPHP48-D/
  8138.        RPL
  8139.        *
  8140.        * Begin the secondary
  8141.        *
  8142.        ::
  8143.          RECLAIMDISP           ( *Claim the alpha display* )
  8144.          ClrDA1IsStat          ( *Temporarily disable clock* )
  8145.        *                       ( *Try removing ClrDA1IsStat* )
  8146.          ZEROZERO              ( #0 #0 )
  8147.          150 150 MAKEGROB      ( #0 #0 150x150grob )
  8148.          XYGROBDISP            (  )
  8149.        *
  8150.        * Draw diagonal lines.  Remember that LINEON requires
  8151.        * requires #x2>#x1!
  8152.        *
  8153.          ZEROZERO              ( #x1 #y1 )
  8154.          149 149               ( #x1 #y1 #x2 #y2 )
  8155.          LINEON                ( *Draw line* )
  8156.          ZERO 149              ( #x1 #y1 )
  8157.          149 ZERO              ( #x1 #y1 #x2 #y2 )
  8158.          LINEON                ( *Draw line* )
  8159.        *
  8160.        * Place text
  8161.        *
  8162.          HARDBUFF
  8163.          75 50 "SCROLLING"     ( HBgrob 75 150 "SCROLLING" )
  8164.          150 CENTER$3x5        ( HBgrob )
  8165.          75 100 "EXAMPLE"      ( HBgrob 75 100 "EXAMPLE" )
  8166.          150 CENTER$3x5        ( HBgrob )
  8167.          DROPFALSE             ( FALSE )
  8168.          { LAM Exit } BIND     ( *Bind POL exit flag* )
  8169.          ' DispMenu.1          ( *Display Action shows menu* )
  8170.          ' ::                  ( *Hard key handler*   )
  8171.            kpNoShift #=casedrop
  8172.              ::
  8173.                 DUP#<7 casedrpfls ( *Enable softkeys* )
  8174.                 kcUpArrow    ?CaseKeyDef
  8175.                                  :: TakeOver SCROLLUP ;
  8176.                 kcLeftArrow  ?CaseKeyDef
  8177.                                  :: TakeOver SCROLLLEFT ;
  8178.                 kcDownArrow  ?CaseKeyDef
  8179.                                  :: TakeOver SCROLLDOWN ;
  8180.  
  8181.  
  8182.  
  8183.                                  Page 121
  8184.  
  8185.  
  8186.  
  8187.  
  8188.  
  8189.  
  8190.                 kcRightArrow ?CaseKeyDef
  8191.                                  :: TakeOver SCROLLRIGHT ;
  8192.                 kcOn         ?CaseKeyDef
  8193.                                  :: TakeOver
  8194.                                     TRUE ' LAM Exit STO ;
  8195.                 kcRightShift   #=casedrpfls
  8196.                 DROP 'DoBadKeyT
  8197.              ;
  8198.            2DROP 'DoBadKeyT
  8199.          ;
  8200.          TrueTrue              ( *Key control flags* )
  8201.          {
  8202.            { "TOP" :: TakeOver JUMPTOP ; }
  8203.            { "BOT" :: TakeOver JUMPBOT ; }
  8204.            { "LEFT" :: TakeOver JUMPLEFT ; }
  8205.            { "RIGHT" :: TakeOver JUMPRIGHT ; }
  8206.            NullMenuKey
  8207.            { "QUIT" :: TakeOver TRUE ' LAM Exit STO ; }
  8208.          }
  8209.          ONEFALSE              ( *1st row, no suspend* )
  8210.          ' LAM Exit            ( *App exit condition* )
  8211.          ' ERRJMP              ( *Error handler* )
  8212.          ParOuterLoop          ( *Run the ParOuterLoop* )
  8213.          RECLAIMDISP           ( *Resize and clear display* )
  8214.          SetDAsBAD             ( *Redraw display* )
  8215.        ;
  8216.  
  8217.        The above code, if stored in a file SCRSFKY.S, can be
  8218.        compiled as follows:
  8219.  
  8220.        RPLCOMPILE SCRSFKY.S
  8221.        SASM SCRSFKY.A
  8222.        SLOAD -H SCRSFKY.M
  8223.  
  8224.        This example also assumes that the file KEYDEFS.H is either
  8225.        in the same directory or the source file has been modified
  8226.        to reflect the location of KEYDEFS.H.  The loader control
  8227.        file SCRSFKY.M looks like this:
  8228.  
  8229.        OU SCRSFKY
  8230.        LL SCRSFKY.LR
  8231.        SU XR
  8232.        SE ENTRIES.O
  8233.        RE SCRSFKY.O
  8234.  
  8235.        The final file, SCRSFKY, may be binary downloaded to the
  8236.        HP 48 for a test.
  8237.  
  8238.        When SCRSFKY is running, the arrow keys scroll the display,
  8239.        and the labeled softkeys move the window to the
  8240.        corresponding boundary.  The [ATTN] key terminates the
  8241.        program.
  8242.  
  8243.  
  8244.  
  8245.  
  8246.  
  8247.  
  8248.  
  8249.                                  Page 122
  8250.  
  8251.  
  8252.  
  8253.  
  8254.        22.  System Commands
  8255.  
  8256.        The following words set, test, or control various system
  8257.        conditions or modes.
  8258.  
  8259.        ALARM?          ( --> flag )
  8260.                          Returns TRUE if an alarm is due
  8261.        AtUserStack     ( --> )
  8262.                          Declares user ownership of all objects
  8263.                          on the stack.
  8264.        CLKTICKS        ( --> hxs )
  8265.                          Returns 13 nibble hex string reflecting
  8266.                          the number of ticks since 01/01/0000.
  8267.                          There are 8192 ticks per second.
  8268.        ClrSysFlag      ( # --> )
  8269.                          Clears system flag from #1 to #64
  8270.        ClrUserFlag     ( # --> )
  8271.                          Clears user flag from #1 to #64
  8272.        DATE            ( --> %date )
  8273.                          Returns real number date
  8274.        DOBEEP          ( %freq %duration --> )
  8275.                          BEEP command
  8276.        DOBIN           ( --> )
  8277.                          Set base mode to BINary
  8278.        DODEC           ( --> )
  8279.                          Set base mode to DECimal
  8280.        DOENG           ( # --> )
  8281.                          Set ENG display with # (0-11) digits
  8282.        DOFIX           ( # --> )
  8283.                          Set FIX display with # (0-11) digits
  8284.        DOHEX           ( --> )
  8285.                          Set base mode to HEXadecimal
  8286.        DOOCT           ( --> )
  8287.                          Set base mode to OCTal
  8288.        DOSCI           ( # --> )
  8289.                          Set SCI display with # (0-11) digits
  8290.        DOSTD           ( --> )
  8291.                          Set STD display mode
  8292.        DPRADIX?        ( --> flag )
  8293.                          Returns TRUE if current radix is .
  8294.                          Returns FALSE if current radix is ,
  8295.        SETDEG          ( --> )
  8296.                          Set DEGREES angle mode
  8297.        SETGRAD         ( --> )
  8298.                          Set GRADS angle mode
  8299.        SETRAD          ( --> )
  8300.                          Set RADIANS angle mode
  8301.        SLOW            ( --> )
  8302.                          15msec delay
  8303.        TOD             ( --> %time )
  8304.                          Returns time of day in h.ms form
  8305.        TestSysFlag     ( # --> flag )
  8306.                          Returns TRUE if system flag # is set
  8307.        TestUserFlag    ( # --> flag )
  8308.                          Returns TRUE if user flag # is set
  8309.        VERYSLOW        ( --> )
  8310.                          300 msec delay
  8311.        VERYVERYSLOW    ( --> )
  8312.  
  8313.  
  8314.  
  8315.                                  Page 123
  8316.  
  8317.  
  8318.  
  8319.  
  8320.  
  8321.  
  8322.                          3 sec delay
  8323.        WORDSIZE        ( --> # )
  8324.                          Returns binary wordsize
  8325.        dostws          ( # --> )
  8326.                          Stores binary wordsize
  8327.        dowait          ( %seconds --> )
  8328.                          Waits for %seconds in light sleep
  8329.  
  8330.  
  8331.  
  8332.  
  8333.  
  8334.  
  8335.  
  8336.  
  8337.  
  8338.  
  8339.  
  8340.  
  8341.  
  8342.  
  8343.  
  8344.  
  8345.  
  8346.  
  8347.  
  8348.  
  8349.  
  8350.  
  8351.  
  8352.  
  8353.  
  8354.  
  8355.  
  8356.  
  8357.  
  8358.  
  8359.  
  8360.  
  8361.  
  8362.  
  8363.  
  8364.  
  8365.  
  8366.  
  8367.  
  8368.  
  8369.  
  8370.  
  8371.  
  8372.  
  8373.  
  8374.  
  8375.  
  8376.  
  8377.  
  8378.  
  8379.  
  8380.  
  8381.                                  Page 124
  8382.  
  8383.